1 /*****************************************************************************
2 * info.c : Playlist info management
3 *****************************************************************************
4 * Copyright (C) 1999-2004 VideoLAN
5 * $Id: info.c,v 1.6 2004/01/23 10:48:08 zorglub Exp $
7 * Authors: Clément Stenac <zorglub@videolan.org>
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.
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.
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() */
31 #include "vlc_playlist.h"
34 * Get one special info
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
43 char * playlist_GetInfo( playlist_t *p_playlist, int i_item,
44 const char * psz_cat, const char *psz_name )
46 /* Check the existence of the playlist */
47 if( p_playlist == NULL)
51 /* Get a correct item */
52 if( i_item >= 0 && i_item < p_playlist->i_size )
55 else if( p_playlist->i_size > 0 )
57 i_item = p_playlist->i_index;
63 return playlist_GetItemInfo( p_playlist->pp_items[i_item] , psz_cat,
68 * Get one special info, from an item (no need for p_playlist)
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
75 char * playlist_GetItemInfo( playlist_item_t *p_item,
76 const char * psz_cat, const char *psz_name )
79 for( i = 0 ; i< p_item->i_categories ; i++ )
81 if( !strcmp( p_item->pp_categories[i]->psz_name , psz_cat ) )
83 for( j = 0 ; j< p_item->pp_categories[i]->i_infos ; j++ )
85 if( !strcmp( p_item->pp_categories[i]->pp_infos[j]->psz_name,
89 strdup(p_item->pp_categories[i]->pp_infos[j]->psz_value );
98 * Get one info category. Create it if it does not exist
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.
106 item_info_category_t *
107 playlist_GetCategory( playlist_t *p_playlist, int i_item,
108 const char * psz_cat )
110 /* Check the existence of the playlist */
111 if( p_playlist == NULL)
116 /* Get a correct item */
117 if( i_item >= 0 && i_item < p_playlist->i_size )
120 else if( p_playlist->i_size > 0 )
122 i_item = p_playlist->i_index;
129 return playlist_GetItemCategory( p_playlist->pp_items[i_item] , psz_cat );
133 * Get one info category (no p_playlist). Create it if it does not exist
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.
139 item_info_category_t *playlist_GetItemCategory( playlist_item_t *p_item,
140 const char *psz_cat )
143 /* Search the category */
144 for( i = 0 ; i< p_item->i_categories ; i++ )
146 if( !strncmp( p_item->pp_categories[i]->psz_name , psz_cat,
149 return p_item->pp_categories[i];
153 /* We did not find the category, create it */
154 return playlist_CreateItemCategory( p_item, psz_cat );
159 * Create one info category.
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.
167 item_info_category_t *
168 playlist_CreateCategory( playlist_t *p_playlist, int i_item,
169 const char * psz_cat )
171 playlist_item_t *p_item = NULL;
173 /* Check the existence of the playlist */
174 if( p_playlist == NULL)
179 /* Get a correct item */
180 if( i_item >= 0 && i_item < p_playlist->i_size )
182 p_item = p_playlist->pp_items[i_item];
184 else if( p_playlist->i_size > 0 )
186 p_item = p_playlist->pp_items[p_playlist->i_index];
193 return playlist_CreateItemCategory( p_item, psz_cat );
197 * Create one info category for an item ( no p_playlist required )
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.
204 item_info_category_t *
205 playlist_CreateItemCategory( playlist_item_t *p_item, const char *psz_cat )
207 item_info_category_t *p_cat;
209 for( i = 0 ; i< p_item->i_categories ; i++)
211 if( !strcmp( p_item->pp_categories[i]->psz_name,psz_cat ) )
213 return p_item->pp_categories[i];
216 if( ( p_cat = malloc( sizeof( item_info_category_t) ) ) == NULL )
221 p_cat->psz_name = strdup( psz_cat);
223 p_cat->pp_infos = NULL;
225 INSERT_ELEM( p_item->pp_categories ,
226 p_item->i_categories ,
227 p_item->i_categories ,
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
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, ...)
251 playlist_item_t *p_item;
254 /* Check the existence of the playlist */
255 if( p_playlist == NULL)
260 /* Get a correct item */
261 if( i_item >= 0 && i_item < p_playlist->i_size )
263 p_item = p_playlist->pp_items[i_item];
265 else if( p_playlist->i_size > 0 )
267 p_item = p_playlist->pp_items[p_playlist->i_index];
274 va_start( args, psz_format );
275 vasprintf( &psz_value, psz_format, args );
278 i_ret = playlist_AddItemInfo( p_item , psz_cat , psz_name , psz_value );
286 * Add info to one item ( no need for p_playlist )
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
294 int playlist_AddItemInfo( playlist_item_t *p_item,
295 const char *psz_cat, const char *psz_name,
296 const char *psz_format, ... )
300 int i_new = VLC_TRUE;
301 item_info_t *p_info = NULL;
302 item_info_category_t *p_cat;
304 /* Find or create the category */
305 p_cat = playlist_GetItemCategory( p_item, psz_cat );
311 for( i = 0 ; i< p_cat->i_infos ; i++)
313 if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) )
315 /* This info is not new */
316 p_info = p_cat->pp_infos[i];
322 /* New info, create it */
325 if( ( p_info = malloc( sizeof( item_info_t) ) ) == NULL )
329 p_info->psz_name = strdup( psz_name);
333 if( p_info->psz_value != NULL ) free( p_info->psz_value ) ;
336 va_start( args, psz_format );
337 vasprintf( &p_info->psz_value, psz_format, args );
340 /* If this is new, insert it */
341 if( i_new == VLC_TRUE )
343 INSERT_ELEM( p_cat->pp_infos,
353 * Add a special info : option
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.
361 int playlist_AddOption( playlist_t *p_playlist, int i_item,
362 const char * psz_format, ...)
365 item_info_t *p_info = NULL;
366 item_info_category_t *p_cat;
368 /* Check the existence of the playlist */
369 if( p_playlist == NULL)
374 /* Get a correct item */
375 if( i_item >= 0 && i_item < p_playlist->i_size )
378 else if( p_playlist->i_size > 0 )
380 i_item = p_playlist->i_index;
387 p_cat = playlist_GetCategory( p_playlist, i_item , "Options" );
394 if( ( p_info = malloc( sizeof( item_info_t) ) ) == NULL )
396 msg_Err( p_playlist, "out of memory" );
400 p_info->psz_name = strdup( "option" );
402 va_start( args, psz_format );
403 vasprintf( &p_info->psz_value, psz_format, args );
406 INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos, p_cat->i_infos, p_info );
412 * Add a option to one item ( no need for p_playlist )
414 * \param p_item the item on which we want the info
415 * \param psz_format the option
416 * \return 0 on success
418 int playlist_AddItemOption( playlist_item_t *p_item,
419 const char *psz_format, ... )
422 item_info_t *p_info = NULL;
423 item_info_category_t *p_cat;
425 p_cat = playlist_GetItemCategory( p_item, "Options" );
431 if( ( p_info = malloc( sizeof( item_info_t) ) ) == NULL )
436 p_info->psz_name = strdup( "option" );
438 va_start( args, psz_format );
439 vasprintf( &p_info->psz_value, psz_format, args );
442 INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos, p_cat->i_infos, p_info );