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