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