]> git.sesse.net Git - vlc/blob - src/control/media_list_path.h
Introduce realloc_or_free() to src/*, and add assert() to mark unhandled ENOMEM error...
[vlc] / src / control / media_list_path.h
1 /*****************************************************************************
2  * media_list_path.h : Some inlined function that allows media_list_path
3  * manipulation. This is internal and used only by media_list_player.
4  *****************************************************************************
5  * Copyright (C) 2005 the VideoLAN team
6  * $Id $
7  *
8  * Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #ifndef _LIBVLC_MEDIA_LIST_PATH_H
26 #define _LIBVLC_MEDIA_LIST_PATH_H 1
27
28 #include <assert.h>
29 #include <vlc_memory.h>
30
31 typedef int * libvlc_media_list_path_t; /* (Media List Player Internal) */
32
33 /**************************************************************************
34  *       path_dump (Media List Player Internal)
35  **************************************************************************/
36 static inline void libvlc_media_list_path_dump( const libvlc_media_list_path_t path )
37 {
38     if(!path)
39     {
40         printf("NULL path\n");
41         return;
42     }
43
44     int i;
45     for(i = 0; path[i] != -1; i++)
46         printf("%s%d", i > 0 ? "/" : "", path[i]);
47     printf("\n");
48 }
49
50 /**************************************************************************
51  *       path_empty (Media List Player Internal)
52  **************************************************************************/
53 static inline libvlc_media_list_path_t libvlc_media_list_path_empty( void )
54 {
55     libvlc_media_list_path_t ret = malloc(sizeof(int));
56     assert( ret );
57     ret[0] = -1;
58     return ret;
59 }
60
61 /**************************************************************************
62  *       path_with_root_index (Media List Player Internal)
63  **************************************************************************/
64 static inline libvlc_media_list_path_t libvlc_media_list_path_with_root_index( int index )
65 {
66     libvlc_media_list_path_t ret = malloc(sizeof(int)*2);
67     assert( ret );
68     ret[0] = index;
69     ret[1] = -1;
70     return ret;
71 }
72
73 /**************************************************************************
74  *       path_depth (Media List Player Internal)
75  **************************************************************************/
76 static inline int libvlc_media_list_path_depth( const libvlc_media_list_path_t path )
77 {
78     int i;
79     for( i = 0; path[i] != -1; i++ );
80     return i;
81 }
82
83 /**************************************************************************
84  *       path_append (Media List Player Internal)
85  **************************************************************************/
86 static inline void libvlc_media_list_path_append( libvlc_media_list_path_t * p_path, int index )
87 {
88     int old_depth = libvlc_media_list_path_depth( *p_path );
89     *p_path = realloc_or_free( *p_path, sizeof(int)*(old_depth+2));
90     assert( *p_path );
91     *p_path[old_depth] = index;
92     *p_path[old_depth+1] = -1;
93 }
94
95 /**************************************************************************
96  *       path_copy_by_appending (Media List Player Internal)
97  **************************************************************************/
98 static inline libvlc_media_list_path_t libvlc_media_list_path_copy_by_appending( const libvlc_media_list_path_t path, int index )
99 {
100     libvlc_media_list_path_t ret;
101     int old_depth = libvlc_media_list_path_depth( path );
102     ret = malloc( sizeof(int) * (old_depth + 2) );
103     assert( ret );
104     memcpy( ret, path, sizeof(int) * old_depth );
105     ret[old_depth] = index;
106     ret[old_depth+1] = -1;
107     return ret;
108 }
109
110 /**************************************************************************
111  *       path_copy (Media List Player Internal)
112  **************************************************************************/
113 static inline libvlc_media_list_path_t libvlc_media_list_path_copy( const libvlc_media_list_path_t path )
114 {
115     libvlc_media_list_path_t ret;
116     int depth = libvlc_media_list_path_depth( path );
117     ret = malloc( sizeof(int)*(depth+1) );
118     assert( ret );
119     memcpy( ret, path, sizeof(int)*(depth+1) );
120     return ret;
121 }
122
123 /**************************************************************************
124  *       get_path_rec (Media List Player Internal)
125  **************************************************************************/
126 static libvlc_media_list_path_t
127 get_path_rec( const libvlc_media_list_path_t path, libvlc_media_list_t * p_current_mlist, libvlc_media_t * p_searched_md )
128 {
129     int i, count;
130     count = libvlc_media_list_count( p_current_mlist, NULL );
131     for( i = 0; i < count; i++ )
132     {
133         libvlc_media_t * p_md = libvlc_media_list_item_at_index( p_current_mlist, i, NULL );
134
135         if( p_md == p_searched_md )
136             return libvlc_media_list_path_copy_by_appending( path, i ); /* Found! */
137
138         libvlc_media_list_t * p_subitems = libvlc_media_subitems( p_md );
139         libvlc_media_release( p_md );
140         if( p_subitems )
141         {
142             libvlc_media_list_path_t new_path = libvlc_media_list_path_copy_by_appending( path, i );
143             libvlc_media_list_lock( p_subitems );
144             libvlc_media_list_path_t ret = get_path_rec( new_path, p_subitems, p_searched_md );
145             libvlc_media_list_unlock( p_subitems );
146             free( new_path );
147             libvlc_media_list_release( p_subitems );
148             if( ret )
149                 return ret; /* Found in sublist! */
150         }
151     }
152     return NULL;
153 }
154
155 /**************************************************************************
156  *       path_of_item (Media List Player Internal)
157  **************************************************************************/
158 static inline libvlc_media_list_path_t libvlc_media_list_path_of_item( libvlc_media_list_t * p_mlist, libvlc_media_t * p_md )
159 {
160     libvlc_media_list_path_t path = libvlc_media_list_path_empty();
161     libvlc_media_list_path_t ret;
162     ret = get_path_rec( path, p_mlist, p_md );
163     free( path );
164     return ret;
165 }
166
167 /**************************************************************************
168  *       item_at_path (Media List Player Internal)
169  **************************************************************************/
170 static libvlc_media_t *
171 libvlc_media_list_item_at_path( libvlc_media_list_t * p_mlist, const libvlc_media_list_path_t path )
172 {
173     libvlc_media_list_t * p_current_mlist = p_mlist;
174     libvlc_media_t * p_md = NULL;
175     int i;
176     for( i = 0; path[i] != -1; i++ )
177     {
178         p_md = libvlc_media_list_item_at_index( p_current_mlist, path[i], NULL );
179
180         if( p_current_mlist != p_mlist )
181             libvlc_media_list_release( p_current_mlist );
182
183         if( path[i+1] == -1 )
184             return p_md;
185
186         p_current_mlist = libvlc_media_subitems( p_md );
187         libvlc_media_release( p_md );
188  
189         if( !p_current_mlist )
190             return NULL;
191
192         /* Fetch next one */
193     }
194     /* Not found, shouldn't happen if the p_path is not empty */
195     if( p_current_mlist != p_mlist )
196         libvlc_media_list_release( p_current_mlist );
197     return NULL;
198 }
199
200 /**************************************************************************
201  *       parentlist_at_path (Media List Player Internal)
202  **************************************************************************/
203 static libvlc_media_list_t *
204 libvlc_media_list_parentlist_at_path( libvlc_media_list_t * p_mlist, const libvlc_media_list_path_t path )
205 {
206     libvlc_media_list_t * p_current_mlist = p_mlist;
207     libvlc_media_t * p_md = NULL;
208     int i;
209     for( i = 0; path[i] != -1; i++ )
210     {
211         if( p_current_mlist != p_mlist )
212             libvlc_media_list_release( p_current_mlist );
213
214         if( path[i+1] == -1 )
215         {
216             libvlc_media_list_retain(p_current_mlist);
217             return p_current_mlist;
218         }
219
220         p_md = libvlc_media_list_item_at_index( p_current_mlist, path[i], NULL );
221
222         p_current_mlist = libvlc_media_subitems( p_md );
223         libvlc_media_release( p_md );
224  
225         if( !p_current_mlist )
226             return NULL;
227
228         /* Fetch next one */
229     }
230     /* Not found, shouldn't happen if the p_path is not empty */
231     if( p_current_mlist != p_mlist )
232         libvlc_media_list_release( p_current_mlist );
233     return NULL;
234 }
235
236 /**************************************************************************
237  *       sublist_at_path (Media List Player Internal)
238  **************************************************************************/
239 static libvlc_media_list_t *
240 libvlc_media_list_sublist_at_path( libvlc_media_list_t * p_mlist, const libvlc_media_list_path_t path )
241 {
242     libvlc_media_list_t * ret;
243     libvlc_media_t * p_md = libvlc_media_list_item_at_path( p_mlist, path );
244     if( !p_md )
245         return NULL;
246  
247     ret = libvlc_media_subitems( p_md );
248     libvlc_media_release( p_md );
249  
250     return ret;
251 }
252
253 #endif