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