]> git.sesse.net Git - mlt/blob - src/framework/mlt_deque.c
src/framework/*: improve the doxygen documentation (work in progress). This also...
[mlt] / src / framework / mlt_deque.c
1 /**
2  * \file mlt_deque.c
3  * \brief double ended queue
4  *
5  * Copyright (C) 2003-2008 Ushodaya Enterprises Limited
6  * \author Charles Yates <charles.yates@pandora.be>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 // Local header files
24 #include "mlt_deque.h"
25
26 // System header files
27 #include <stdlib.h>
28 #include <string.h>
29
30 /** \brief Deque entry class
31  *
32  */
33
34 typedef union
35 {
36         void *addr;
37         int value;
38         double floating;
39 }
40 deque_entry;
41
42 /** \brief Double-Ended Queue (deque) class
43  *
44  * The double-ended queue is a very versatile data structure. MLT uses it as
45  * list, stack, and circular queue.
46  */
47
48 struct mlt_deque_s
49 {
50         deque_entry *list;
51         int size;
52         int count;
53 };
54
55 /** Create a deque.
56  *
57  * \public \memberof mlt_deque_s
58  * \return a new deque
59  */
60
61 mlt_deque mlt_deque_init( )
62 {
63         mlt_deque this = malloc( sizeof( struct mlt_deque_s ) );
64         if ( this != NULL )
65         {
66                 this->list = NULL;
67                 this->size = 0;
68                 this->count = 0;
69         }
70         return this;
71 }
72
73 /** Return the number of items in the deque.
74  *
75  * \public \memberof mlt_deque_s
76  * \param this a deque
77  * \return the number of items
78  */
79
80 int mlt_deque_count( mlt_deque this )
81 {
82         return this->count;
83 }
84
85 /** Allocate space on the deque.
86  *
87  * \private \memberof mlt_deque_s
88  * \param this a deque
89  * \return true if there was an error
90  */
91
92 static int mlt_deque_allocate( mlt_deque this )
93 {
94         if ( this->count == this->size )
95         {
96                 this->list = realloc( this->list, sizeof( deque_entry ) * ( this->size + 20 ) );
97                 this->size += 20;
98         }
99         return this->list == NULL;
100 }
101
102 /** Push an item to the end.
103  *
104  * \public \memberof mlt_deque_s
105  * \param this a deque
106  * \param item an opaque pointer
107  * \return true if there was an error
108  */
109
110 int mlt_deque_push_back( mlt_deque this, void *item )
111 {
112         int error = mlt_deque_allocate( this );
113
114         if ( error == 0 )
115                 this->list[ this->count ++ ].addr = item;
116
117         return error;
118 }
119
120 /** Pop an item.
121  *
122  * \public \memberof mlt_deque_s
123  * \param this a pointer
124  * \return an opaque pointer
125  */
126
127 void *mlt_deque_pop_back( mlt_deque this )
128 {
129         return this->count > 0 ? this->list[ -- this->count ].addr : NULL;
130 }
131
132 /** Queue an item at the start.
133  *
134  * \public \memberof mlt_deque_s
135  * \param this a deque
136  * \param item an opaque pointer
137  * \return true if there was an error
138  */
139
140 int mlt_deque_push_front( mlt_deque this, void *item )
141 {
142         int error = mlt_deque_allocate( this );
143
144         if ( error == 0 )
145         {
146                 memmove( &this->list[ 1 ], this->list, ( this->count ++ ) * sizeof( deque_entry ) );
147                 this->list[ 0 ].addr = item;
148         }
149
150         return error;
151 }
152
153 /** Remove an item from the start.
154  *
155  * \public \memberof mlt_deque_s
156  * \param this a pointer
157  * \return an opaque pointer
158  */
159
160 void *mlt_deque_pop_front( mlt_deque this )
161 {
162         void *item = NULL;
163
164         if ( this->count > 0 )
165         {
166                 item = this->list[ 0 ].addr;
167                 memmove( this->list, &this->list[ 1 ], ( -- this->count ) * sizeof( deque_entry ) );
168         }
169
170         return item;
171 }
172
173 /** Inquire on item at back of deque but don't remove.
174  *
175  * \public \memberof mlt_deque_s
176  * \param this a deque
177  * \return an opaque pointer
178  */
179
180 void *mlt_deque_peek_back( mlt_deque this )
181 {
182         return this->count > 0 ? this->list[ this->count - 1 ].addr : NULL;
183 }
184
185 /** Inquire on item at front of deque but don't remove.
186  *
187  * \public \memberof mlt_deque_s
188  * \param this a deque
189  * \return an opaque pointer
190  */
191
192 void *mlt_deque_peek_front( mlt_deque this )
193 {
194         return this->count > 0 ? this->list[ 0 ].addr : NULL;
195 }
196
197 /** Push an integer to the end.
198  *
199  * \public \memberof mlt_deque_s
200  * \param this a deque
201  * \param item an integer
202  * \return true if there was an error
203  */
204
205 int mlt_deque_push_back_int( mlt_deque this, int item )
206 {
207         int error = mlt_deque_allocate( this );
208
209         if ( error == 0 )
210                 this->list[ this->count ++ ].value = item;
211
212         return error;
213 }
214
215 /** Pop an integer.
216  *
217  * \public \memberof mlt_deque_s
218  * \param this a deque
219  * \return an integer
220  */
221
222 int mlt_deque_pop_back_int( mlt_deque this )
223 {
224         return this->count > 0 ? this->list[ -- this->count ].value : 0;
225 }
226
227 /** Queue an integer at the start.
228  *
229  * \public \memberof mlt_deque_s
230  * \param this a deque
231  * \param item an integer
232  * \return true if there was an error
233  */
234
235 int mlt_deque_push_front_int( mlt_deque this, int item )
236 {
237         int error = mlt_deque_allocate( this );
238
239         if ( error == 0 )
240         {
241                 memmove( &this->list[ 1 ], this->list, ( this->count ++ ) * sizeof( deque_entry ) );
242                 this->list[ 0 ].value = item;
243         }
244
245         return error;
246 }
247
248 /** Remove an integer from the start.
249  *
250  * \public \memberof mlt_deque_s
251  * \param this a deque
252  * \return an integer
253  */
254
255 int mlt_deque_pop_front_int( mlt_deque this )
256 {
257         int item = 0;
258
259         if ( this->count > 0 )
260         {
261                 item = this->list[ 0 ].value;
262                 memmove( this->list, &this->list[ 1 ], ( -- this->count ) * sizeof( deque_entry ) );
263         }
264
265         return item;
266 }
267
268 /** Inquire on an integer at back of deque but don't remove.
269  *
270  * \public \memberof mlt_deque_s
271  * \param this a deque
272  * \return an integer
273  */
274
275 int mlt_deque_peek_back_int( mlt_deque this )
276 {
277         return this->count > 0 ? this->list[ this->count - 1 ].value : 0;
278 }
279
280 /** Inquire on an integer at front of deque but don't remove.
281  *
282  * \public \memberof mlt_deque_s
283  * \param this a deque
284  * \return an integer
285  */
286
287 int mlt_deque_peek_front_int( mlt_deque this )
288 {
289         return this->count > 0 ? this->list[ 0 ].value : 0;
290 }
291
292 /** Push a double float to the end.
293  *
294  * \public \memberof mlt_deque_s
295  * \param this a deque
296  * \param item a double float
297  * \return true if there was an error
298  */
299
300 int mlt_deque_push_back_double( mlt_deque this, double item )
301 {
302         int error = mlt_deque_allocate( this );
303
304         if ( error == 0 )
305                 this->list[ this->count ++ ].floating = item;
306
307         return error;
308 }
309
310 /** Pop a double float.
311  *
312  * \public \memberof mlt_deque_s
313  * \param this a deque
314  * \return a double float
315  */
316
317 double mlt_deque_pop_back_double( mlt_deque this )
318 {
319         return this->count > 0 ? this->list[ -- this->count ].floating : 0;
320 }
321
322 /** Queue a double float at the start.
323  *
324  * \public \memberof mlt_deque_s
325  * \param this a deque
326  * \param item a double float
327  * \return true if there was an error
328  */
329
330 int mlt_deque_push_front_double( mlt_deque this, double item )
331 {
332         int error = mlt_deque_allocate( this );
333
334         if ( error == 0 )
335         {
336                 memmove( &this->list[ 1 ], this->list, ( this->count ++ ) * sizeof( deque_entry ) );
337                 this->list[ 0 ].floating = item;
338         }
339
340         return error;
341 }
342
343 /** Remove a double float from the start.
344  *
345  * \public \memberof mlt_deque_s
346  * \param this a deque
347  * \return a double float
348  */
349
350 double mlt_deque_pop_front_double( mlt_deque this )
351 {
352         double item = 0;
353
354         if ( this->count > 0 )
355         {
356                 item = this->list[ 0 ].floating;
357                 memmove( this->list, &this->list[ 1 ], ( -- this->count ) * sizeof( deque_entry ) );
358         }
359
360         return item;
361 }
362
363 /** Inquire on a double float at back of deque but don't remove.
364  *
365  * \public \memberof mlt_deque_s
366  * \param this a deque
367  * \return a double float
368  */
369
370 double mlt_deque_peek_back_double( mlt_deque this )
371 {
372         return this->count > 0 ? this->list[ this->count - 1 ].floating : 0;
373 }
374
375 /** Inquire on a double float at front of deque but don't remove.
376  *
377  * \public \memberof mlt_deque_s
378  * \param this a deque
379  * \return a double float
380  */
381
382 double mlt_deque_peek_front_double( mlt_deque this )
383 {
384         return this->count > 0 ? this->list[ 0 ].floating : 0;
385 }
386
387 /** Destroy the queue.
388  *
389  * \public \memberof mlt_deque_s
390  * \param this a deque
391  */
392
393 void mlt_deque_close( mlt_deque this )
394 {
395         free( this->list );
396         free( this );
397 }