]> git.sesse.net Git - vlc/blob - src/control/media_list_path.h
correct realloc() usage, on failure realloc will return NULL
[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 /**************************************************************************
29  *       path_empty (Media List Player Internal)
30  **************************************************************************/
31 static inline libvlc_media_list_path_t libvlc_media_list_path_empty( void )
32 {
33     libvlc_media_list_path_t ret = malloc(sizeof(int));
34     ret[0] = -1;
35     return ret;
36 }
37
38 /**************************************************************************
39  *       path_with_root_index (Media List Player Internal)
40  **************************************************************************/
41 static inline libvlc_media_list_path_t libvlc_media_list_path_with_root_index( int index )
42 {
43     libvlc_media_list_path_t ret = malloc(sizeof(int)*2);
44     ret[0] = index;
45     ret[1] = -1;
46     return ret;
47 }
48
49 /**************************************************************************
50  *       path_deepness (Media List Player Internal)
51  **************************************************************************/
52 static inline int libvlc_media_list_path_deepness( libvlc_media_list_path_t path )
53 {
54     int i;
55     for( i = 0; path[i] != -1; i++ );
56     return i;
57 }
58
59 /**************************************************************************
60  *       path_append (Media List Player Internal)
61  **************************************************************************/
62 static inline void libvlc_media_list_path_append( libvlc_media_list_path_t * p_path, int index )
63 {
64     libvlc_media_list_path_t *p_tmp;
65     int old_deepness = libvlc_media_list_path_deepness( *p_path );
66     *p_tmp = realloc( *p_path, sizeof(int)*(old_deepness+2));
67     if( *p_tmp )
68     {
69         *p_tmp = *p_path;
70         *p_path[old_deepness] = index;
71         *p_path[old_deepness+1] = -1;
72     }
73 }
74
75 /**************************************************************************
76  *       path_copy_by_appending (Media List Player Internal)
77  **************************************************************************/
78 static inline libvlc_media_list_path_t libvlc_media_list_path_copy_by_appending( libvlc_media_list_path_t path, int index )
79 {
80     libvlc_media_list_path_t ret;
81     int old_deepness = libvlc_media_list_path_deepness( path );
82     ret = malloc( sizeof(int)*(old_deepness+2) );
83     memcpy( ret, path, sizeof(int)*(old_deepness+2) );
84     ret[old_deepness] = index;
85     ret[old_deepness+1] = -1;
86     return ret;
87 }
88
89 /**************************************************************************
90  *       path_copy (Media List Player Internal)
91  **************************************************************************/
92 static inline libvlc_media_list_path_t libvlc_media_list_path_copy( libvlc_media_list_path_t path )
93 {
94     libvlc_media_list_path_t ret;
95     int deepness = libvlc_media_list_path_deepness( path );
96     ret = malloc( sizeof(int)*(deepness+1) );
97     memcpy( ret, path, sizeof(int)*(deepness+1) );
98     return ret;
99 }
100
101 /**************************************************************************
102  *       get_path_rec (Media List Player Internal)
103  **************************************************************************/
104 static libvlc_media_list_path_t
105 get_path_rec( libvlc_media_list_path_t path, libvlc_media_list_t * p_current_mlist, libvlc_media_t * p_searched_md )
106 {
107     int i, count;
108     count = libvlc_media_list_count( p_current_mlist, NULL );
109     for( i = 0; i < count; i++ )
110     {
111         libvlc_media_t * p_md = libvlc_media_list_item_at_index( p_current_mlist, i, NULL );
112
113         if( p_md == p_searched_md )
114             return libvlc_media_list_path_copy_by_appending( path, i ); /* Found! */
115
116         libvlc_media_list_t * p_subitems = libvlc_media_subitems( p_md, NULL );
117         libvlc_media_release( p_md );
118         if( p_subitems )
119         {
120             libvlc_media_list_path_t new_path = libvlc_media_list_path_copy_by_appending( path, i );
121             libvlc_media_list_lock( p_subitems );
122             libvlc_media_list_path_t ret = get_path_rec( new_path, p_subitems, p_searched_md );
123             libvlc_media_list_unlock( p_subitems );
124             free( new_path );
125             libvlc_media_list_release( p_subitems );
126             if( ret )
127                 return ret; /* Found in sublist! */
128         }
129     }
130     return NULL;
131 }
132
133 /**************************************************************************
134  *       path_of_item (Media List Player Internal)
135  **************************************************************************/
136 static inline libvlc_media_list_path_t libvlc_media_list_path_of_item( libvlc_media_list_t * p_mlist, libvlc_media_t * p_md )
137 {
138     libvlc_media_list_path_t path = libvlc_media_list_path_empty();
139     libvlc_media_list_path_t ret;
140     ret = get_path_rec( path, p_mlist, p_md );
141     free( path );
142     return ret;
143 }
144
145 /**************************************************************************
146  *       item_at_path (Media List Player Internal)
147  **************************************************************************/
148 static libvlc_media_t *
149 libvlc_media_list_item_at_path( libvlc_media_list_t * p_mlist, libvlc_media_list_path_t path )
150 {
151     libvlc_media_list_t * p_current_mlist = p_mlist;
152     libvlc_media_t * p_md = NULL;
153     int i;
154     for( i = 0; path[i] != -1; i++ )
155     {
156         p_md = libvlc_media_list_item_at_index( p_current_mlist, path[i], NULL );
157
158         if( p_current_mlist != p_mlist )
159             libvlc_media_list_release( p_current_mlist );
160
161         if( path[i+1] == -1 )
162             return p_md;
163
164         p_current_mlist = libvlc_media_subitems( p_md, NULL );
165         libvlc_media_release( p_md );
166  
167         if( !p_current_mlist )
168             return NULL;
169
170         /* Fetch next one */
171     }
172     /* Not found, shouldn't happen if the p_path is not empty */
173     if( p_current_mlist != p_mlist )
174         libvlc_media_list_release( p_current_mlist );
175     return NULL;
176 }
177
178 /**************************************************************************
179  *       parentlist_at_path (Media List Player Internal)
180  **************************************************************************/
181 static libvlc_media_list_t *
182 libvlc_media_list_parentlist_at_path( libvlc_media_list_t * p_mlist, libvlc_media_list_path_t path )
183 {
184     libvlc_media_list_t * p_current_mlist = p_mlist;
185     libvlc_media_t * p_md = NULL;
186     int i;
187     for( i = 0; path[i] != -1; i++ )
188     {
189         if( p_current_mlist != p_mlist )
190             libvlc_media_list_release( p_current_mlist );
191
192         if( path[i+1] == -1 )
193             return p_current_mlist;
194
195         p_md = libvlc_media_list_item_at_index( p_current_mlist, path[i], NULL );
196
197         p_current_mlist = libvlc_media_subitems( p_md, NULL );
198         libvlc_media_release( p_md );
199  
200         if( !p_current_mlist )
201             return NULL;
202
203         /* Fetch next one */
204     }
205     /* Not found, shouldn't happen if the p_path is not empty */
206     if( p_current_mlist != p_mlist )
207         libvlc_media_list_release( p_current_mlist );
208     return NULL;
209 }
210
211 /**************************************************************************
212  *       sublist_at_path (Media List Player Internal)
213  **************************************************************************/
214 static libvlc_media_list_t *
215 libvlc_media_list_sublist_at_path( libvlc_media_list_t * p_mlist, libvlc_media_list_path_t path )
216 {
217     libvlc_media_list_t * ret;
218     libvlc_media_t * p_md = libvlc_media_list_item_at_path( p_mlist, path );
219     if( !p_md )
220         return NULL;
221  
222     ret = libvlc_media_subitems( p_md, NULL );
223     libvlc_media_release( p_md );
224  
225     return ret;
226 }
227
228 #endif