]> git.sesse.net Git - vlc/blob - modules/demux/playlist/pls.c
pls.c: ported to new api, at least tried to.
[vlc] / modules / demux / playlist / pls.c
1 /*****************************************************************************
2  * pls.c : PLS playlist format import
3  *****************************************************************************
4  * Copyright (C) 2004 VideoLAN
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
8  * Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 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 General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <stdlib.h>                                      /* malloc(), free() */
29
30 #include <vlc/vlc.h>
31 #include <vlc/input.h>
32 #include <vlc/intf.h>
33
34 #include <errno.h>                                                 /* ENOMEM */
35 #include "playlist.h"
36
37 struct demux_sys_t
38 {
39     char *psz_prefix;
40 };
41
42 /*****************************************************************************
43  * Local prototypes
44  *****************************************************************************/
45 static int Demux( demux_t *p_demux);
46 static int Control( demux_t *p_demux, int i_query, va_list args );
47
48 /*****************************************************************************
49  * Import_PLS: main import function
50  *****************************************************************************/
51 int Import_PLS( vlc_object_t *p_this )
52 {
53     demux_t *p_demux = (demux_t *)p_this;
54
55     uint8_t *p_peek;
56     char    *psz_ext;
57
58     if( stream_Peek( p_demux->s , &p_peek, 7 ) < 7 )
59     {
60         msg_Err( p_demux, "cannot peek" );
61         return VLC_EGENERIC;
62     }
63     psz_ext = strrchr ( p_demux->psz_path, '.' );
64
65     if( !strncasecmp( p_peek, "[playlist]", 10 ) )
66     {
67         ;
68     }
69     else if( ( psz_ext && !strcasecmp( psz_ext, ".pls") ) ||
70              ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "pls") ) )
71     {
72         ;
73     }
74     else
75     {
76         msg_Warn(p_demux, "pls import module discarded");
77         return VLC_EGENERIC;
78         
79     }
80     msg_Dbg( p_demux, "found valid PLS playlist file");
81
82     p_demux->pf_control = Control;
83     p_demux->pf_demux = Demux;
84     p_demux->p_sys = malloc( sizeof(demux_sys_t) );
85     if( p_demux->p_sys == NULL )
86     {
87         msg_Err( p_demux, "Out of memory" );
88         return VLC_ENOMEM;
89     }
90     p_demux->p_sys->psz_prefix = FindPrefix( p_demux );
91
92     return VLC_SUCCESS;
93 }
94
95 /*****************************************************************************
96  * Deactivate: frees unused data
97  *****************************************************************************/
98 void Close_PLS( vlc_object_t *p_this )
99 {
100     demux_t *p_demux = (demux_t *)p_this;
101     if( p_demux->p_sys->psz_prefix )
102     {
103         free( p_demux->p_sys->psz_prefix );
104     }
105     free( p_demux->p_sys );
106 }
107
108 static int Demux( demux_t *p_demux )
109 {
110     mtime_t        i_duration = -1;
111     char          *psz_name = NULL;    
112     char          *psz_line;
113     char          *psz_mrl = NULL;
114     char          *psz_key;
115     char          *psz_value;
116     playlist_t    *p_playlist;
117     int            i_position;
118     int            i_item = -1;
119     int            i_new_item = 0;
120     int            i_key_length;
121     playlist_item_t *p_parent;
122
123     p_playlist = (playlist_t *) vlc_object_find( p_demux, VLC_OBJECT_PLAYLIST,
124                                                  FIND_PARENT );
125     if( !p_playlist )
126     {
127         msg_Err( p_demux, "can't find playlist" );
128         return -1;
129     }
130     p_parent = p_playlist->status.p_item;
131     p_parent->input.i_type = ITEM_TYPE_PLAYLIST;
132
133 //    p_playlist->pp_items[p_playlist->i_index]->b_autodeletion = VLC_TRUE;
134     /* Change the item to a node */     
135     if( p_parent->i_children == -1)     
136     {   
137         playlist_ItemToNode( p_playlist,p_parent );     
138     }    
139     while( ( psz_line = stream_ReadLine( p_demux->s ) ) )
140     {
141         if( !strncasecmp( psz_line, "[playlist]", sizeof("[playlist]")-1 ) )
142         {
143             free( psz_line );
144             continue;
145         }
146         psz_key = psz_line;
147         psz_value = strchr( psz_line, '=' );
148         if( psz_value )
149         {
150             *psz_value='\0';
151             psz_value++;
152         }
153         else
154         {
155             msg_Warn( p_demux, "invalid line in pls file" );
156             free( psz_line );
157             continue;
158         }
159         if( !strcasecmp( psz_key, "version" ) )
160         {
161             msg_Dbg( p_demux, "pls file version: %s", psz_value );
162             free( psz_line );
163             continue;
164         }
165         /* find the number part of of file1, title1 or length1 etc */
166         i_key_length = strlen( psz_key );
167         if( i_key_length >= 5 ) /* file1 type case */
168         {
169             i_new_item = atoi( psz_key + 4 );
170             if( i_new_item == 0 && i_key_length >= 6 ) /* title1 type case */
171             {
172                 i_new_item = atoi( psz_key + 5 );
173                 if( i_new_item == 0 && i_key_length >= 7 ) /* length1 type case */
174                 {
175                     i_new_item = atoi( psz_key + 6 );
176                 }
177             }
178         }
179         if( i_new_item == 0 )
180         {
181             msg_Warn( p_demux, "couldn't find number of items" );
182             free( psz_line );
183             continue;
184         }
185         if( i_item == -1 )
186         {
187             i_item = i_new_item;
188         }
189         /* we found a new item, insert the previous */
190         if( i_item != i_new_item )
191         {
192             if( psz_mrl )
193             {
194                 playlist_item_t *p_item = playlist_ItemNew( p_playlist, psz_mrl,
195                                                             psz_name );
196                 
197                 playlist_NodeAddItem( p_playlist,p_item,        
198                                       p_parent->pp_parents[0]->i_view,  
199                                       p_parent, 
200                                       PLAYLIST_APPEND, PLAYLIST_END );  
201                 
202                 playlist_CopyParents( p_parent, p_item );
203                 if( i_duration != -1 )
204                 {
205                     //playlist_SetDuration( p_playlist, i_position, i_duration );
206                 }
207                 i_position++;
208                 free( psz_mrl );
209                 psz_mrl = NULL;
210             }
211             else
212             {
213                 msg_Warn( p_demux, "no file= part found for item %d", i_item );
214             }
215             if( psz_name )
216             {
217                 free( psz_name );
218                 psz_name = NULL;
219             }
220             i_duration = -1;
221             i_item = i_new_item;
222             i_new_item = 0;
223         }
224         if( !strncasecmp( psz_key, "file", sizeof("file") -1 ) )
225         {
226             psz_mrl = ProcessMRL( psz_value, p_demux->p_sys->psz_prefix );
227         }
228         else if( !strncasecmp( psz_key, "title", sizeof("title") -1 ) )
229         {
230             psz_name = strdup( psz_value );
231         }
232         else if( !strncasecmp( psz_key, "length", sizeof("length") -1 ) )
233         {
234             i_duration = atoi( psz_value );
235             if( i_duration != -1 )
236             {
237                 i_duration *= 1000000;
238             }
239         }
240         else
241         {
242             msg_Warn( p_demux, "unknown key found in pls file: %s", psz_key );
243         }
244         free( psz_line );
245     }
246     /* Add last object */
247     if( psz_mrl )
248     {
249         playlist_item_t *p_item = playlist_ItemNew( p_playlist, psz_mrl,
250                                                     psz_name );
251         
252         playlist_NodeAddItem( p_playlist,p_item,        
253                               p_parent->pp_parents[0]->i_view,  
254                               p_parent, 
255                               PLAYLIST_APPEND, PLAYLIST_END );  
256                 
257         playlist_CopyParents( p_parent, p_item );
258         if( i_duration != -1 )
259         {
260             //playlist_SetDuration( p_playlist, i_position, i_duration );
261         }
262         free( psz_mrl );
263         psz_mrl = NULL;
264     }
265     else
266     {
267         msg_Warn( p_demux, "no file= part found for item %d", i_item );
268     }
269     if( psz_name )
270     {
271         free( psz_name );
272         psz_name = NULL;
273     }
274
275     vlc_object_release( p_playlist );
276     return VLC_SUCCESS;
277 }
278
279 static int Control( demux_t *p_demux, int i_query, va_list args )
280 {
281     return VLC_EGENERIC;
282 }