lib/media_list: fix sign warnings
[vlc.git] / lib / 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 VLC authors and VideoLAN
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 it
11  * under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program; if not, write to the Free Software Foundation,
22  * 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_dump (Media List Player Internal)
32  **************************************************************************/
33 static inline void libvlc_media_list_path_dump( const libvlc_media_list_path_t path )
34 {
35     if(!path)
36     {
37         printf("NULL path\n");
38         return;
39     }
40
41     for(int i = 0; path[i] != -1; i++)
42         printf("%s%d", i > 0 ? "/" : "", path[i]);
43     printf("\n");
44 }
45
46 /**************************************************************************
47  *       path_empty (Media List Player Internal)
48  **************************************************************************/
49 static inline libvlc_media_list_path_t libvlc_media_list_path_empty( void )
50 {
51     libvlc_media_list_path_t ret = xmalloc(sizeof(int));
52     ret[0] = -1;
53     return ret;
54 }
55
56 /**************************************************************************
57  *       path_with_root_index (Media List Player Internal)
58  **************************************************************************/
59 static inline libvlc_media_list_path_t libvlc_media_list_path_with_root_index( int index )
60 {
61     libvlc_media_list_path_t ret = xmalloc(sizeof(int)*2);
62     ret[0] = index;
63     ret[1] = -1;
64     return ret;
65 }
66
67 /**************************************************************************
68  *       path_depth (Media List Player Internal)
69  **************************************************************************/
70 static inline int libvlc_media_list_path_depth( const libvlc_media_list_path_t path )
71 {
72     int i;
73     for( i = 0; path[i] != -1; i++ );
74     return i;
75 }
76
77 /**************************************************************************
78  *       path_append (Media List Player Internal)
79  **************************************************************************/
80 static inline void libvlc_media_list_path_append( libvlc_media_list_path_t * p_path, int index )
81 {
82     int old_depth = libvlc_media_list_path_depth( *p_path );
83     *p_path = xrealloc( *p_path, sizeof(int)*(old_depth+2));
84     *p_path[old_depth] = index;
85     *p_path[old_depth+1] = -1;
86 }
87
88 /**************************************************************************
89  *       path_copy_by_appending (Media List Player Internal)
90  **************************************************************************/
91 static inline libvlc_media_list_path_t libvlc_media_list_path_copy_by_appending( const libvlc_media_list_path_t path, int index )
92 {
93     libvlc_media_list_path_t ret;
94     int old_depth = libvlc_media_list_path_depth( path );
95     ret = xmalloc( sizeof(int) * (old_depth + 2) );
96     memcpy( ret, path, sizeof(int) * old_depth );
97     ret[old_depth] = index;
98     ret[old_depth+1] = -1;
99     return ret;
100 }
101
102 /**************************************************************************
103  *       path_copy (Media List Player Internal)
104  **************************************************************************/
105 static inline libvlc_media_list_path_t libvlc_media_list_path_copy( const libvlc_media_list_path_t path )
106 {
107     libvlc_media_list_path_t ret;
108     int depth = libvlc_media_list_path_depth( path );
109     ret = xmalloc( sizeof(int)*(depth+1) );
110     memcpy( ret, path, sizeof(int)*(depth+1) );
111     return ret;
112 }
113
114 /**************************************************************************
115  *       get_path_rec (Media List Player Internal)
116  **************************************************************************/
117 static libvlc_media_list_path_t
118 get_path_rec( const libvlc_media_list_path_t path, libvlc_media_list_t * p_current_mlist, libvlc_media_t * p_searched_md )
119 {
120     int count = libvlc_media_list_count( p_current_mlist );
121
122     for( int i = 0; i < count; i++ )
123     {
124         libvlc_media_t * p_md = libvlc_media_list_item_at_index( p_current_mlist, i );
125
126         if( p_md == p_searched_md )
127             return libvlc_media_list_path_copy_by_appending( path, i ); /* Found! */
128
129         libvlc_media_list_t * p_subitems = libvlc_media_subitems( p_md );
130         libvlc_media_release( p_md );
131         if( p_subitems )
132         {
133             libvlc_media_list_path_t new_path = libvlc_media_list_path_copy_by_appending( path, i );
134             libvlc_media_list_lock( p_subitems );
135             libvlc_media_list_path_t ret = get_path_rec( new_path, p_subitems, p_searched_md );
136             libvlc_media_list_unlock( p_subitems );
137             free( new_path );
138             libvlc_media_list_release( p_subitems );
139             if( ret )
140                 return ret; /* Found in sublist! */
141         }
142     }
143     return NULL;
144 }
145
146 /**************************************************************************
147  *       path_of_item (Media List Player Internal)
148  **************************************************************************/
149 static inline libvlc_media_list_path_t libvlc_media_list_path_of_item( libvlc_media_list_t * p_mlist, libvlc_media_t * p_md )
150 {
151     libvlc_media_list_path_t path = libvlc_media_list_path_empty();
152     libvlc_media_list_path_t ret;
153     ret = get_path_rec( path, p_mlist, p_md );
154     free( path );
155     return ret;
156 }
157
158 /**************************************************************************
159  *       item_at_path (Media List Player Internal)
160  **************************************************************************/
161 static libvlc_media_t *
162 libvlc_media_list_item_at_path( libvlc_media_list_t * p_mlist, const libvlc_media_list_path_t path )
163 {
164     libvlc_media_list_t * p_current_mlist = p_mlist;
165
166     for( int i = 0; path[i] != -1; i++ )
167     {
168         libvlc_media_t* p_md = libvlc_media_list_item_at_index( p_current_mlist, path[i] );
169
170         if( p_current_mlist != p_mlist )
171             libvlc_media_list_release( p_current_mlist );
172
173         if( path[i+1] == -1 )
174             return p_md;
175
176         p_current_mlist = libvlc_media_subitems( p_md );
177         libvlc_media_release( p_md );
178
179         if( !p_current_mlist )
180             return NULL;
181
182         /* Fetch next one */
183     }
184     /* Not found, shouldn't happen if the p_path is not empty */
185     if( p_current_mlist != p_mlist )
186         libvlc_media_list_release( p_current_mlist );
187     return NULL;
188 }
189
190 /**************************************************************************
191  *       parentlist_at_path (Media List Player Internal)
192  **************************************************************************/
193 static libvlc_media_list_t *
194 libvlc_media_list_parentlist_at_path( libvlc_media_list_t * p_mlist, const libvlc_media_list_path_t path )
195 {
196     libvlc_media_list_t * p_current_mlist = p_mlist;
197
198     for( int i = 0; path[i] != -1; i++ )
199     {
200         if( p_current_mlist != p_mlist )
201             libvlc_media_list_release( p_current_mlist );
202
203         if( path[i+1] == -1 )
204         {
205             libvlc_media_list_retain(p_current_mlist);
206             return p_current_mlist;
207         }
208
209         libvlc_media_t* p_md = libvlc_media_list_item_at_index( p_current_mlist, path[i] );
210
211         p_current_mlist = libvlc_media_subitems( p_md );
212         libvlc_media_release( p_md );
213
214         if( !p_current_mlist )
215             return NULL;
216
217         /* Fetch next one */
218     }
219     /* Not found, shouldn't happen if the p_path is not empty */
220     if( p_current_mlist != p_mlist )
221         libvlc_media_list_release( p_current_mlist );
222     return NULL;
223 }
224
225 /**************************************************************************
226  *       sublist_at_path (Media List Player Internal)
227  **************************************************************************/
228 static libvlc_media_list_t *
229 libvlc_media_list_sublist_at_path( libvlc_media_list_t * p_mlist, const libvlc_media_list_path_t path )
230 {
231     libvlc_media_list_t * ret;
232     libvlc_media_t * p_md = libvlc_media_list_item_at_path( p_mlist, path );
233     if( !p_md )
234         return NULL;
235
236     ret = libvlc_media_subitems( p_md );
237     libvlc_media_release( p_md );
238
239     return ret;
240 }
241
242 #endif