]> git.sesse.net Git - vlc/blob - src/playlist/info.c
Options as infos were bad in several ways: it broke PLAYLIST_GO, used
[vlc] / src / playlist / info.c
1 /*****************************************************************************
2  * info.c : Playlist info management
3  *****************************************************************************
4  * Copyright (C) 1999-2004 VideoLAN
5  * $Id: info.c,v 1.8 2004/01/29 17:51:08 zorglub Exp $
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23 #include <stdlib.h>                                      /* free(), strtol() */
24 #include <stdio.h>                                              /* sprintf() */
25 #include <string.h>                                            /* strerror() */
26
27 #include <vlc/vlc.h>
28 #include <vlc/vout.h>
29 #include <vlc/sout.h>
30
31 #include "vlc_playlist.h"
32
33 /**
34  * Get one special info
35  * Must be entered with playlist lock
36  *
37  * \param p_playlist the playlist to get the info from
38  * \param i_item position of the item on
39  *               which we want the info ( -1 for current )
40  * \param psz_cat the category in which the info is stored
41  * \param psz_name the name of the info
42  * \return the info value if any, an empty string else
43 */
44 char * playlist_GetInfo( playlist_t *p_playlist, int i_pos,
45                          const char * psz_cat, const char *psz_name )
46 {
47     playlist_item_t *p_item;
48     char *psz_buffer;
49     /* Check the existence of the playlist */
50     if( p_playlist == NULL)
51     {
52         return strdup("");
53     }
54     p_item = playlist_ItemGetByPos( p_playlist, i_pos );
55     if( !p_item )
56     {
57         return strdup("");
58     }
59     vlc_mutex_lock( &p_item->lock );
60     psz_buffer = playlist_ItemGetInfo( p_item ,
61                                        psz_cat, psz_name );
62     vlc_mutex_unlock( &p_item->lock );
63
64     return psz_buffer;
65 }
66
67 /**
68  *  Get one special info, from an item (no need for p_playlist)
69  *
70  * \param p_item the item on which we want the info
71  * \param psz_cat the category in which the info is stored
72  * \param psz_name the name of the info
73  * \return the info value if any, an empty string else
74 */
75 char * playlist_ItemGetInfo( playlist_item_t *p_item,
76                       const char * psz_cat, const char *psz_name )
77 {
78      int i,j ;
79      for( i = 0 ; i< p_item->i_categories ; i++ )
80      {
81          if( !strcmp( p_item->pp_categories[i]->psz_name , psz_cat ) )
82          {
83              for( j = 0 ; j< p_item->pp_categories[i]->i_infos ; j++ )
84              {
85                  if( !strcmp( p_item->pp_categories[i]->pp_infos[j]->psz_name,
86                                          psz_name ) )
87                  {
88                      return
89                      strdup(p_item->pp_categories[i]->pp_infos[j]->psz_value );
90                  }
91              }
92          }
93      }
94      return strdup("");
95 }
96
97 /**
98  * Get one info category. Create it if it does not exist
99  *
100  * \param p_playlist the playlist to get the category from
101  * \param i_item the position of the item on which we want
102  *               the info ( -1 for current )
103  * \param psz_cat the category we want
104  * \return the info category.
105  */
106 item_info_category_t *
107 playlist_GetCategory( playlist_t *p_playlist, int i_pos,
108                       const char * psz_cat )
109 {
110     playlist_item_t *p_item;
111     /* Check the existence of the playlist */
112     if( p_playlist == NULL)
113     {
114         return NULL;
115     }
116     p_item=  playlist_ItemGetByPos( p_playlist , i_pos );
117     if( !p_item )
118     {
119         return NULL;
120     }
121     return playlist_ItemGetCategory( p_item , psz_cat );
122 }
123
124 /**
125  * Get one info category (no p_playlist). Create it if it does not exist
126  *
127  * \param p_item the playlist item to get the category from
128  * \param psz_cat the category we want
129  * \return the info category.
130  */
131 item_info_category_t *playlist_ItemGetCategory( playlist_item_t *p_item,
132                                                 const char *psz_cat )
133 {
134     int i;
135     /* Search the category */
136     for( i = 0 ; i< p_item->i_categories ; i++ )
137     {
138         if( !strncmp( p_item->pp_categories[i]->psz_name , psz_cat,
139                                 strlen(psz_cat) ) )
140         {
141             return p_item->pp_categories[i];
142         }
143     }
144
145     /* We did not find the category, create it */
146     return playlist_ItemCreateCategory( p_item, psz_cat );
147 }
148
149
150 /**
151  * Create one info category.
152  *
153  * \param p_playlist the playlist
154  * \param i_item the position of the item for which we create
155  *               the category ( -1 for current )
156  * \param psz_cat the category we want to create
157  * \return the info category.
158  */
159 item_info_category_t *
160 playlist_CreateCategory( playlist_t *p_playlist, int i_pos,
161                          const char * psz_cat )
162 {
163     playlist_item_t *p_item = NULL;
164
165     /* Check the existence of the playlist */
166     if( p_playlist == NULL)
167     {
168         return NULL;
169     }
170     p_item = playlist_ItemGetByPos( p_playlist , i_pos );
171     if( !p_item )
172     {
173         return NULL;
174     }
175
176     return playlist_ItemCreateCategory( p_item, psz_cat );
177 }
178
179 /**
180  * Create one info category for an item ( no p_playlist required )
181  *
182  * \param p_playlist the playlist
183  * \param p_item the item to create category for
184  * \param psz_cat the category we want to create
185  * \return the info category.
186  */
187 item_info_category_t *
188 playlist_ItemCreateCategory( playlist_item_t *p_item, const char *psz_cat )
189 {
190     item_info_category_t *p_cat;
191     int i;
192     for( i = 0 ; i< p_item->i_categories ; i++)
193     {
194         if( !strcmp( p_item->pp_categories[i]->psz_name,psz_cat ) )
195         {
196             return p_item->pp_categories[i];
197         }
198     }
199     if( ( p_cat = malloc( sizeof( item_info_category_t) ) ) == NULL )
200     {
201         return NULL;
202     }
203
204     p_cat->psz_name = strdup( psz_cat);
205     p_cat->i_infos = 0;
206     p_cat->pp_infos = NULL;
207
208     INSERT_ELEM( p_item->pp_categories ,
209                  p_item->i_categories ,
210                  p_item->i_categories ,
211                  p_cat );
212
213     return p_cat;
214 }
215
216 /**
217  * Add an info item
218  *
219  * \param p_playlist the playlist
220  * \param i_item the position of the item on which we want
221  *               the info ( -1 for current )
222  * \param psz_cat the category we want to put the info into
223  *                (gets created if needed)
224  * \param psz_name the name of the info
225  * \param psz_format printf-style info
226  * \return VLC_SUCCESS
227  */
228 int playlist_AddInfo( playlist_t *p_playlist, int i_item,
229                       const char * psz_cat, const char *psz_name,
230                       const char * psz_format, ...)
231 {
232     va_list args;
233     int i_ret;
234     playlist_item_t *p_item;
235     char *psz_value;
236
237     /* Check the existence of the playlist */
238     if( p_playlist == NULL)
239     {
240         return VLC_EGENERIC;
241     }
242
243     p_item = playlist_ItemGetByPos( p_playlist, i_item );
244     if( !p_item )
245     {
246             return VLC_ENOOBJ;
247     }
248
249     va_start( args, psz_format );
250     vasprintf( &psz_value, psz_format, args );
251     va_end( args );
252
253     vlc_mutex_lock( &p_item->lock );
254     i_ret = playlist_ItemAddInfo( p_item , psz_cat , psz_name , psz_value );
255     vlc_mutex_unlock( &p_item->lock );
256
257     free( psz_value );
258     return i_ret;
259 }
260
261
262 /**
263  *  Add info to one item ( no need for p_playlist )
264  *
265  * \param p_item the item for which we add the info
266  * \param psz_cat the category in which the info is stored
267  * \param psz_name the name of the info
268  * \param psz_format printf-style info
269  * \return VLC_SUCCESS on success
270 */
271 int playlist_ItemAddInfo( playlist_item_t *p_item,
272                       const char *psz_cat, const char *psz_name,
273                       const char *psz_format, ... )
274 {
275     va_list args;
276     int i;
277     int i_new = VLC_TRUE;
278     item_info_t *p_info = NULL;
279     item_info_category_t *p_cat;
280
281     /* Find or create the category */
282     p_cat = playlist_ItemGetCategory( p_item, psz_cat );
283     if( p_cat == NULL)
284     {
285         return VLC_EGENERIC;
286     }
287
288     for( i = 0 ; i< p_cat->i_infos ; i++)
289     {
290         if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) )
291         {
292             /* This info is not new */
293             p_info = p_cat->pp_infos[i];
294             i_new = VLC_FALSE;
295             break;
296         }
297     }
298
299     /* New info, create it */
300     if( p_info == NULL )
301     {
302         if( ( p_info = malloc( sizeof( item_info_t) ) ) == NULL )
303         {
304             return VLC_EGENERIC;
305         }
306         p_info->psz_name = strdup( psz_name);
307     }
308     else
309     {
310         if( p_info->psz_value != NULL ) free( p_info->psz_value ) ;
311     }
312
313     va_start( args, psz_format );
314     vasprintf( &p_info->psz_value, psz_format, args );
315     va_end( args );
316
317     /* If this is new, insert it */
318     if( i_new == VLC_TRUE )
319     {
320         INSERT_ELEM( p_cat->pp_infos,
321                      p_cat->i_infos,
322                      p_cat->i_infos,
323                      p_info );
324     }
325
326     return VLC_SUCCESS;
327 }
328
329 /**
330  * Add a special info : option
331  *
332  * \param p_playlist the playlist
333  * \param i_item the position of the item on which we
334  *               add the option ( -1 for current )
335  * \param psz_value the option to add
336  * \return the info category.
337  */
338 int playlist_AddOption( playlist_t *p_playlist, int i_pos,
339                         const char *psz_option)
340 {
341     playlist_item_t *p_item;
342
343     /* Check the existence of the playlist */
344     if( p_playlist == NULL)
345     {
346         return VLC_EGENERIC;
347     }
348
349     p_item = playlist_ItemGetByPos( p_playlist , i_pos );
350     if( !p_item )
351     {
352             return VLC_ENOOBJ;
353     }
354
355     vlc_mutex_lock( &p_item->lock );
356     INSERT_ELEM( p_item->ppsz_options,
357                  p_item->i_options,
358                  p_item->i_options,
359                  (char *)psz_option );
360     vlc_mutex_unlock( &p_item->lock );
361
362     return VLC_SUCCESS;
363 }
364
365 /**
366  *  Add a option to one item ( no need for p_playlist )
367  *
368  * \param p_item the item on which we want the info
369  * \param psz_format the option
370  * \return 0 on success
371 */
372 int playlist_ItemAddOption( playlist_item_t *p_item,
373                             const char *psz_option )
374 {
375     INSERT_ELEM( p_item->ppsz_options,
376                  p_item->i_options,
377                  p_item->i_options,
378                  (char *)psz_option);
379
380     return VLC_SUCCESS;
381 }