1 /*****************************************************************************
2 * zpl.c : ZPL playlist format import
3 *****************************************************************************
4 * Copyright (C) 2009 the VideoLAN team
6 * Authors: Su Heaven <suheaven@gmail.com>
7 * RĂ©mi Duraffort <ivoire@videolan.org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 * You should have received a copy of the GNU General Public License along with
20 * this program; if not, write to the Free Software Foundation, Inc., 51
21 * Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_demux.h>
34 #include <vlc_charset.h>
43 /*****************************************************************************
45 *****************************************************************************/
46 static int Demux( demux_t
*p_demux
);
47 static int Control( demux_t
*p_demux
, int i_query
, va_list args
);
48 static char* ParseTabValue(char* psz_string
);
50 /*****************************************************************************
51 * Import_ZPL: main import function
52 *****************************************************************************/
53 int Import_ZPL( vlc_object_t
*p_this
)
55 demux_t
*p_demux
= (demux_t
*)p_this
;
57 if(! ( demux_IsPathExtension( p_demux
, ".zpl" ) || demux_IsForced( p_demux
, "zpl" )))
60 STANDARD_DEMUX_INIT_MSG( "found valid ZPL playlist" );
61 p_demux
->p_sys
->psz_prefix
= FindPrefix( p_demux
);
67 /*****************************************************************************
68 * Deactivate: frees unused data
69 *****************************************************************************/
70 void Close_ZPL( vlc_object_t
*p_this
)
72 demux_t
*p_demux
= (demux_t
*)p_this
;
73 free( p_demux
->p_sys
->psz_prefix
);
74 free( p_demux
->p_sys
);
77 static int Demux( demux_t
*p_demux
)
81 mtime_t i_duration
= -1;
82 char *psz_title
= NULL
, *psz_genre
= NULL
, *psz_tracknum
= NULL
,
83 *psz_language
= NULL
, *psz_artist
= NULL
, *psz_album
= NULL
,
84 *psz_date
= NULL
, *psz_publicher
= NULL
, *psz_encodedby
= NULL
,
85 *psz_description
= NULL
, *psz_url
= NULL
, *psz_copyright
= NULL
,
88 input_item_t
*p_current_input
= GetCurrentItem(p_demux
);
90 psz_line
= stream_ReadLine( p_demux
->s
);
91 char *psz_parse
= psz_line
;
93 /* Skip leading tabs and spaces */
94 while( *psz_parse
== ' ' || *psz_parse
== '\t' ||
95 *psz_parse
== '\n' || *psz_parse
== '\r' )
98 /* if the 1st line is "AC", skip it */
99 /* TODO: using this information ? */
100 if( !strncasecmp( psz_parse
, "AC", strlen( "AC" ) ) )
103 psz_line
= stream_ReadLine( p_demux
->s
);
106 input_item_node_t
*p_subitems
= input_item_node_Create( p_current_input
);
108 /* Loop on all lines */
111 psz_parse
= psz_line
;
113 /* Skip leading tabs and spaces */
114 while( *psz_parse
== ' ' || *psz_parse
== '\t' ||
115 *psz_parse
== '\n' || *psz_parse
== '\r' )
119 if( !strncasecmp( psz_parse
, "NM", strlen( "NM" ) ) )
121 char *psz_tabvalue
= ParseTabValue( psz_parse
);
122 if( !EMPTY_STR(psz_tabvalue
) )
124 psz_mrl
= ProcessMRL( psz_tabvalue
, p_demux
->p_sys
->psz_prefix
);
126 free( psz_tabvalue
);
130 else if( !strncasecmp( psz_parse
, "DR", strlen( "DR" ) ) )
132 char *psz_tabvalue
= ParseTabValue( psz_parse
);
133 if( !EMPTY_STR(psz_tabvalue
) )
135 int i_parsed_duration
= atoi( psz_tabvalue
);
136 if( i_parsed_duration
>= 0 )
137 i_duration
= i_parsed_duration
* INT64_C(1000);
139 free( psz_tabvalue
);
142 #define PARSE(tag,variable) \
143 else if( !strncasecmp( psz_parse, tag, strlen( tag ) ) ) \
144 variable = ParseTabValue( psz_parse );
146 PARSE( "TT", psz_title
)
147 PARSE( "TG", psz_genre
)
148 PARSE( "TR", psz_tracknum
)
149 PARSE( "TL", psz_language
)
150 PARSE( "TA", psz_artist
)
151 PARSE( "TB", psz_album
)
152 PARSE( "TY", psz_date
)
153 PARSE( "TH", psz_publicher
)
154 PARSE( "TE", psz_encodedby
)
155 PARSE( "TC", psz_description
)
156 PARSE( "TU", psz_url
)
157 PARSE( "TO", psz_copyright
)
161 /* force a duration ? */
162 else if( !strncasecmp( psz_parse
, "FD", strlen( "FD" ) ) )
165 /* end of file entry */
166 else if( !strncasecmp( psz_parse
, "BR!", strlen( "BR!" ) ) )
168 /* create the input item */
169 input_item_t
*p_input
= input_item_NewExt( p_demux
, psz_mrl
,
170 psz_title
, 0, NULL
, 0, i_duration
);
171 input_item_AddSubItem( p_current_input
, p_input
);
172 input_item_node_AppendItem( p_subitems
, p_input
);
174 FREENULL( psz_title
);
177 #define SET(variable, type) \
178 if( !EMPTY_STR(variable) ) \
180 input_item_Set##type( p_input, variable ); \
181 FREENULL( variable ); \
184 SET( psz_genre
, Genre
);
185 SET( psz_tracknum
, TrackNum
);
186 SET( psz_language
, Language
);
187 SET( psz_artist
, Artist
);
188 SET( psz_album
, Album
);
189 SET( psz_date
, Date
);
190 SET( psz_encodedby
, EncodedBy
);
191 SET( psz_description
, Description
);
192 SET( psz_copyright
, Copyright
);
195 vlc_gc_decref( p_input
);
198 msg_Warn( p_demux
, "invalid line '%s'", psz_parse
);
200 /* Fetch another line */
202 psz_line
= stream_ReadLine( p_demux
->s
);
205 input_item_AddSubItemTree( p_subitems
);
206 input_item_node_Delete( p_subitems
);
208 vlc_gc_decref(p_current_input
);
209 var_Destroy( p_demux
, "zpl-extvlcopt" );
210 return 0; /* Needed for correct operation of go back */
213 static int Control( demux_t
*p_demux
, int i_query
, va_list args
)
215 VLC_UNUSED(p_demux
); VLC_UNUSED(i_query
); VLC_UNUSED(args
);
219 static char* ParseTabValue(char* psz_string
)
221 int i_len
= strlen( psz_string
);
224 char* psz_value
= calloc( i_len
, 1 );
228 sscanf( psz_string
,"%*[^=]=%[^\r\t\n]", psz_value
);