* String review, round one
[vlc.git] / src / playlist / info.c
1 /*****************************************************************************
2  * info.c : Playlist info management
3  *****************************************************************************
4  * Copyright (C) 1999-2004 VideoLAN
5  * $Id: info.c,v 1.7 2004/01/25 17:16:06 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  *
36  * \param p_playlist the playlist to get the info from
37  * \param i_item position of the item on
38  *               which we want the info ( -1 for current )
39  * \param psz_cat the category in which the info is stored
40  * \param psz_name the name of the info
41  * \return the info value if any, an empty string else
42 */
43 char * playlist_GetInfo( playlist_t *p_playlist, int i_item,
44                          const char * psz_cat, const char *psz_name )
45 {
46     /* Check the existence of the playlist */
47     if( p_playlist == NULL)
48     {
49         return strdup("");
50     }
51     /* Get a correct item */
52     if( i_item >= 0 && i_item < p_playlist->i_size )
53     {
54     }
55     else if( p_playlist->i_size > 0 )
56     {
57         i_item = p_playlist->i_index;
58     }
59     else
60     {
61         return strdup("");
62     }
63     return playlist_GetItemInfo( p_playlist->pp_items[i_item] , psz_cat,
64                                  psz_name );
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_GetItemInfo( 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_item,
108                       const char * psz_cat )
109 {
110     /* Check the existence of the playlist */
111     if( p_playlist == NULL)
112     {
113         return NULL;
114     }
115
116     /* Get a correct item */
117     if( i_item >= 0 && i_item < p_playlist->i_size )
118     {
119     }
120     else if( p_playlist->i_size > 0 )
121     {
122         i_item = p_playlist->i_index;
123     }
124     else
125     {
126         return NULL;
127     }
128
129     return playlist_GetItemCategory( p_playlist->pp_items[i_item] , psz_cat );
130 }
131
132 /**
133  * Get one info category (no p_playlist). Create it if it does not exist
134  *
135  * \param p_item the playlist item to get the category from
136  * \param psz_cat the category we want
137  * \return the info category.
138  */
139 item_info_category_t *playlist_GetItemCategory( playlist_item_t *p_item,
140                                                 const char *psz_cat )
141 {
142     int i;
143     /* Search the category */
144     for( i = 0 ; i< p_item->i_categories ; i++ )
145     {
146         if( !strncmp( p_item->pp_categories[i]->psz_name , psz_cat,
147                                 strlen(psz_cat) ) )
148         {
149             return p_item->pp_categories[i];
150         }
151     }
152
153     /* We did not find the category, create it */
154     return playlist_CreateItemCategory( p_item, psz_cat );
155 }
156
157
158 /**
159  * Create one info category.
160  *
161  * \param p_playlist the playlist
162  * \param i_item the position of the item for which we create
163  *               the category ( -1 for current )
164  * \param psz_cat the category we want to create
165  * \return the info category.
166  */
167 item_info_category_t *
168 playlist_CreateCategory( playlist_t *p_playlist, int i_item,
169                          const char * psz_cat )
170 {
171     playlist_item_t *p_item = NULL;
172
173     /* Check the existence of the playlist */
174     if( p_playlist == NULL)
175     {
176         return NULL;
177     }
178
179     /* Get a correct item */
180     if( i_item >= 0 && i_item < p_playlist->i_size )
181     {
182         p_item = p_playlist->pp_items[i_item];
183     }
184     else if( p_playlist->i_size > 0 )
185     {
186         p_item = p_playlist->pp_items[p_playlist->i_index];
187     }
188     else
189     {
190         return NULL;
191     }
192
193     return playlist_CreateItemCategory( p_item, psz_cat );
194 }
195
196 /**
197  * Create one info category for an item ( no p_playlist required )
198  *
199  * \param p_playlist the playlist
200  * \param p_item the item to create category for
201  * \param psz_cat the category we want to create
202  * \return the info category.
203  */
204 item_info_category_t *
205 playlist_CreateItemCategory( playlist_item_t *p_item, const char *psz_cat )
206 {
207     item_info_category_t *p_cat;
208     int i;
209     for( i = 0 ; i< p_item->i_categories ; i++)
210     {
211         if( !strcmp( p_item->pp_categories[i]->psz_name,psz_cat ) )
212         {
213             return p_item->pp_categories[i];
214         }
215     }
216     if( ( p_cat = malloc( sizeof( item_info_category_t) ) ) == NULL )
217     {
218         return NULL;
219     }
220
221     p_cat->psz_name = strdup( psz_cat);
222     p_cat->i_infos = 0;
223     p_cat->pp_infos = NULL;
224
225     INSERT_ELEM( p_item->pp_categories ,
226                  p_item->i_categories ,
227                  p_item->i_categories ,
228                  p_cat );
229
230     return p_cat;
231 }
232
233 /**
234  * Add an info item
235  *
236  * \param p_playlist the playlist
237  * \param i_item the position of the item on which we want
238  *               the info ( -1 for current )
239  * \param psz_cat the category we want to put the info into
240  *                (gets created if needed)
241  * \param psz_name the name of the info
242  * \param psz_format printf-style info
243  * \return VLC_SUCCESS
244  */
245 int playlist_AddInfo( playlist_t *p_playlist, int i_item,
246                       const char * psz_cat, const char *psz_name,
247                       const char * psz_format, ...)
248 {
249     va_list args;
250     int i_ret;
251     playlist_item_t *p_item;
252     char *psz_value;
253
254     /* Check the existence of the playlist */
255     if( p_playlist == NULL)
256     {
257         return VLC_EGENERIC;
258     }
259
260     /* Get a correct item */
261     if( i_item >= 0 && i_item < p_playlist->i_size )
262     {
263         p_item = p_playlist->pp_items[i_item];
264     }
265     else if( p_playlist->i_size > 0 )
266     {
267         p_item = p_playlist->pp_items[p_playlist->i_index];
268     }
269     else
270     {
271         return VLC_EGENERIC;
272     }
273
274     va_start( args, psz_format );
275     vasprintf( &psz_value, psz_format, args );
276     va_end( args );
277
278     i_ret = playlist_AddItemInfo( p_item , psz_cat , psz_name , psz_value );
279
280     free( psz_value );
281     return i_ret;
282 }
283
284
285 /**
286  *  Add info to one item ( no need for p_playlist )
287  *
288  * \param p_item the item for which we add the info
289  * \param psz_cat the category in which the info is stored
290  * \param psz_name the name of the info
291  * \param psz_format printf-style info
292  * \return VLC_SUCCESS on success
293 */
294 int playlist_AddItemInfo( playlist_item_t *p_item,
295                       const char *psz_cat, const char *psz_name,
296                       const char *psz_format, ... )
297 {
298     va_list args;
299     int i;
300     int i_new = VLC_TRUE;
301     item_info_t *p_info = NULL;
302     item_info_category_t *p_cat;
303
304     /* Find or create the category */
305     p_cat = playlist_GetItemCategory( p_item, psz_cat );
306     if( p_cat == NULL)
307     {
308         return VLC_EGENERIC;
309     }
310
311     for( i = 0 ; i< p_cat->i_infos ; i++)
312     {
313         if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) )
314         {
315             /* This info is not new */
316             p_info = p_cat->pp_infos[i];
317             i_new = VLC_FALSE;
318             break;
319         }
320     }
321
322     /* New info, create it */
323     if( p_info == NULL )
324     {
325         if( ( p_info = malloc( sizeof( item_info_t) ) ) == NULL )
326         {
327             return VLC_EGENERIC;
328         }
329         p_info->psz_name = strdup( psz_name);
330     }
331     else
332     {
333         if( p_info->psz_value != NULL ) free( p_info->psz_value ) ;
334     }
335
336     va_start( args, psz_format );
337     vasprintf( &p_info->psz_value, psz_format, args );
338     va_end( args );
339
340     /* If this is new, insert it */
341     if( i_new == VLC_TRUE )
342     {
343         INSERT_ELEM( p_cat->pp_infos,
344                      p_cat->i_infos,
345                      p_cat->i_infos,
346                      p_info );
347     }
348
349     return VLC_SUCCESS;
350 }
351
352 /**
353  * Add a special info : option
354  *
355  * \param p_playlist the playlist
356  * \param i_item the position of the item on which we
357  *               add the option ( -1 for current )
358  * \param psz_value the option to add
359  * \return the info category.
360  */
361 int playlist_AddOption( playlist_t *p_playlist, int i_item,
362                         const char * psz_format, ...)
363 {
364     va_list args;
365     item_info_t *p_info = NULL;
366     item_info_category_t *p_cat;
367
368     /* Check the existence of the playlist */
369     if( p_playlist == NULL)
370     {
371         return VLC_EGENERIC;
372     }
373
374     /* Get a correct item */
375     if( i_item >= 0 && i_item < p_playlist->i_size )
376     {
377     }
378     else if( p_playlist->i_size > 0 )
379     {
380         i_item = p_playlist->i_index;
381     }
382     else
383     {
384         return VLC_EGENERIC;
385     }
386
387     p_cat = playlist_GetCategory( p_playlist, i_item , _("Options") );
388
389     if( p_cat == NULL)
390     {
391         return VLC_EGENERIC;
392     }
393
394     if( ( p_info = malloc( sizeof( item_info_t) ) ) == NULL )
395     {
396         msg_Err( p_playlist, "out of memory" );
397         return VLC_EGENERIC;
398     }
399
400     p_info->psz_name = strdup( "option" );
401
402     va_start( args, psz_format );
403     vasprintf( &p_info->psz_value, psz_format, args );
404     va_end( args );
405
406     INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos, p_cat->i_infos, p_info );
407
408     return VLC_SUCCESS;
409 }
410
411 /**
412  *  Add a option to one item ( no need for p_playlist )
413  *
414  * \param p_item the item on which we want the info
415  * \param psz_format the option
416  * \return 0 on success
417 */
418 int playlist_AddItemOption( playlist_item_t *p_item,
419                             const char *psz_format, ... )
420 {
421     va_list args;
422     item_info_t *p_info = NULL;
423     item_info_category_t *p_cat;
424
425     p_cat = playlist_GetItemCategory( p_item, _("Options") );
426     if( p_cat == NULL)
427     {
428         return VLC_EGENERIC;
429     }
430
431     if( ( p_info = malloc( sizeof( item_info_t) ) ) == NULL )
432     {
433         return VLC_EGENERIC;
434     }
435
436     p_info->psz_name = strdup( "option" );
437
438     va_start( args, psz_format );
439     vasprintf( &p_info->psz_value, psz_format, args );
440     va_end( args );
441
442     INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos, p_cat->i_infos, p_info );
443
444     return VLC_SUCCESS;
445 }