1 /*****************************************************************************
2 * info.c : Playlist info management
3 *****************************************************************************
4 * Copyright (C) 1999-2004 VideoLAN
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() */
28 #include <vlc/input.h>
30 #include "vlc_playlist.h"
33 * Get one special info
34 * Must be entered with playlist lock
36 * \param p_playlist the playlist to get the info from
37 * \param i_pos 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_pos,
44 const char *psz_cat, const char *psz_name )
46 playlist_item_t *p_item;
50 if( p_playlist == NULL) return strdup("");
52 p_item = playlist_ItemGetByPos( p_playlist, i_pos );
53 if( !p_item ) return strdup("");
55 vlc_mutex_lock( &p_item->input.lock );
56 psz_buffer = playlist_ItemGetInfo( p_item , psz_cat, psz_name );
57 vlc_mutex_unlock( &p_item->input.lock );
63 * Get one special info, from an item (no need for p_playlist)
65 * \param p_item the item on which we want the info
66 * \param psz_cat the category in which the info is stored
67 * \param psz_name the name of the info
68 * \return the info value if any, an empty string else
70 char * playlist_ItemGetInfo( playlist_item_t *p_item,
71 const char * psz_cat, const char *psz_name )
75 for( i = 0 ; i< p_item->input.i_categories ; i++ )
77 info_category_t *p_category = p_item->input.pp_categories[i];
79 if( strcmp( p_category->psz_name , psz_cat ) ) continue;
81 for( j = 0 ; j< p_category->i_infos ; j++ )
83 if( !strcmp( p_category->pp_infos[j]->psz_name, psz_name) )
85 return strdup( p_category->pp_infos[j]->psz_value );
93 * Get one info category (no p_playlist). Create it if it does not exist
95 * \param p_item the playlist item to get the category from
96 * \param psz_cat the category we want
97 * \return the info category.
99 info_category_t * playlist_ItemGetCategory( playlist_item_t *p_item,
100 const char *psz_cat )
103 /* Search the category */
104 for( i = 0 ; i< p_item->input.i_categories ; i++ )
106 if( !strncmp( p_item->input.pp_categories[i]->psz_name, psz_cat,
109 return p_item->input.pp_categories[i];
113 /* We did not find the category, create it */
114 return playlist_ItemCreateCategory( p_item, psz_cat );
118 * Create one info category for an item ( no p_playlist required )
120 * \param p_item the item to create category for
121 * \param psz_cat the category we want to create
122 * \return the info category.
124 info_category_t * playlist_ItemCreateCategory( playlist_item_t *p_item,
125 const char *psz_cat )
127 info_category_t *p_cat;
130 for( i = 0 ; i< p_item->input.i_categories ; i++)
132 if( !strcmp( p_item->input.pp_categories[i]->psz_name,psz_cat ) )
134 return p_item->input.pp_categories[i];
138 if( ( p_cat = malloc( sizeof( info_category_t) ) ) == NULL )
143 p_cat->psz_name = strdup( psz_cat);
145 p_cat->pp_infos = NULL;
147 INSERT_ELEM( p_item->input.pp_categories, p_item->input.i_categories,
148 p_item->input.i_categories, p_cat );
156 * \param p_playlist the playlist
157 * \param i_item the position of the item on which we want
158 * the info ( -1 for current )
159 * \param psz_cat the category we want to put the info into
160 * (gets created if needed)
161 * \param psz_name the name of the info
162 * \param psz_format printf-style info
163 * \return VLC_SUCCESS
165 int playlist_AddInfo( playlist_t *p_playlist, int i_item,
166 const char * psz_cat, const char *psz_name,
167 const char * psz_format, ...)
171 playlist_item_t *p_item;
175 if( p_playlist == NULL) return VLC_EGENERIC;
177 p_item = playlist_ItemGetByPos( p_playlist, i_item );
178 if( !p_item ) return VLC_ENOOBJ;
180 va_start( args, psz_format );
181 vasprintf( &psz_value, psz_format, args );
184 vlc_mutex_lock( &p_item->input.lock );
185 i_ret = playlist_ItemAddInfo( p_item, psz_cat, psz_name, psz_value );
186 vlc_mutex_unlock( &p_item->input.lock );
193 * Add info to one item ( no need for p_playlist )
195 * \param p_item the item for which we add the info
196 * \param psz_cat the category in which the info is stored
197 * \param psz_name the name of the info
198 * \param psz_format printf-style info
199 * \return VLC_SUCCESS on success
201 int playlist_ItemAddInfo( playlist_item_t *p_item,
202 const char *psz_cat, const char *psz_name,
203 const char *psz_format, ... )
207 int i_new = VLC_TRUE;
208 info_t *p_info = NULL;
209 info_category_t *p_cat;
211 /* Find or create the category */
212 p_cat = playlist_ItemGetCategory( p_item, psz_cat );
213 if( p_cat == NULL) return VLC_EGENERIC;
215 for( i = 0 ; i< p_cat->i_infos ; i++)
217 if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) )
219 /* This info is not new */
220 p_info = p_cat->pp_infos[i];
226 /* New info, create it */
229 if( ( p_info = malloc( sizeof( info_t) ) ) == NULL )
233 p_info->psz_name = strdup( psz_name);
237 if( p_info->psz_value != NULL ) free( p_info->psz_value ) ;
240 va_start( args, psz_format );
241 vasprintf( &p_info->psz_value, psz_format, args );
244 /* If this is new, insert it */
245 if( i_new == VLC_TRUE )
247 INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos, p_cat->i_infos, p_info );