From 23458725ce766bcb7fd908b392948a1449a760c6 Mon Sep 17 00:00:00 2001 From: Christophe Mutricy Date: Fri, 12 Aug 2005 14:20:06 +0000 Subject: [PATCH] =?UTF-8?q?ALL:=20Improvements=20in=20the=20M3U=20output?= =?UTF-8?q?=20and=20parser.=20Patch=20by=20Daniel=20Str=C3=A4nger.=20=20?= =?UTF-8?q?=20=20=20=20(Put=20both=20artist=20and=20name,=20protect=20comm?= =?UTF-8?q?a=20with=20\=20)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- THANKS | 1 + modules/demux/playlist/m3u.c | 91 +++++++++++++++++++++++++++++------- modules/misc/playlist/m3u.c | 42 ++++++++++++++--- 3 files changed, 110 insertions(+), 24 deletions(-) diff --git a/THANKS b/THANKS index 5f60d5ba3b..064e0fd71c 100644 --- a/THANKS +++ b/THANKS @@ -31,6 +31,7 @@ Christopher Johnson - Qt fix in vlc.spec Colin Simmonds - compile fix for Mac OS X Damian Ivereigh - ac3dec uninitialized data structure fix Damien Fouilleul - DirectShow input improvements +Daniel Stränger - M3U improvements David Kennedy - X11 fullscreen patch David Weber - Mac OS X interface design & graphics (v0.5.0) Davor Orel - Mac OS X icons diff --git a/modules/demux/playlist/m3u.c b/modules/demux/playlist/m3u.c index dcd3d037c2..5d48cbacde 100644 --- a/modules/demux/playlist/m3u.c +++ b/modules/demux/playlist/m3u.c @@ -44,6 +44,7 @@ struct demux_sys_t *****************************************************************************/ static int Demux( demux_t *p_demux); static int Control( demux_t *p_demux, int i_query, va_list args ); +static void parseEXTINF( char *psz_string, char **ppsz_author, char **ppsz_name, int *pi_duration ); /***************************************************************************** * Import_M3U: main import function @@ -108,10 +109,12 @@ static int Demux( demux_t *p_demux ) playlist_t *p_playlist; char *psz_line; - char *psz_name = NULL; - mtime_t i_duration = -1; - char **ppsz_options = NULL; - int i_options = 0, i; + char *psz_name = NULL; + char *psz_author = NULL; + int i_parsed_duration = 0; + mtime_t i_duration = -1; + char **ppsz_options = NULL; + int i_options = 0, i; playlist_item_t *p_item, *p_current; @@ -155,20 +158,13 @@ static int Demux( demux_t *p_demux ) if( !strncasecmp( psz_parse, "EXTINF:", sizeof("EXTINF:") -1 ) ) { /* Extended info */ - char *psz_duration; psz_parse += sizeof("EXTINF:") - 1; - while( *psz_parse == '\t' || *psz_parse == ' ' ) psz_parse++; - - psz_duration = psz_parse; - psz_parse = strchr( psz_parse, ',' ); - if( psz_parse ) - { - *psz_parse = '\0'; - psz_parse++; - psz_name = strdup( psz_parse ); - i_duration = atoi( psz_duration ); - if( i_duration != -1 ) i_duration *= 1000000; - } + parseEXTINF( psz_parse, &psz_author, &psz_name, &i_parsed_duration ); + i_duration = i_parsed_duration * 1000000; + if ( psz_name ) + psz_name = strdup( psz_name ); + if ( psz_author ) + psz_author = strdup( psz_author ); } else if( !strncasecmp( psz_parse, "EXTVLCOPT:", sizeof("EXTVLCOPT:") -1 ) ) @@ -209,7 +205,9 @@ static int Demux( demux_t *p_demux ) playlist_ItemAddOption( p_item, ppsz_options[i] ); } p_item->input.i_duration = i_duration; - + if ( psz_author ) + vlc_input_item_AddInfo( &p_item->input, _("Meta-information"), + _("Artist"), "%s", psz_author ); playlist_NodeAddItem( p_playlist, p_item, p_current->pp_parents[0]->i_view, p_current, PLAYLIST_APPEND, @@ -240,6 +238,9 @@ static int Demux( demux_t *p_demux ) ppsz_options = NULL; i_options = 0; if( psz_name ) free( psz_name ); psz_name = NULL; + if ( psz_author ) free( psz_author ); + psz_author = NULL; + i_parsed_duration = 0; i_duration = -1; b_cleanup = VLC_FALSE; @@ -264,3 +265,57 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) { return VLC_EGENERIC; } + +static void parseEXTINF(char *psz_string, char **ppsz_author, + char **ppsz_name, int *pi_duration) +{ + char *end=NULL; + char *psz_item=NULL; + + end = psz_string + strlen( psz_string ); + + /* ignore whitespaces */ + for (; psz_string < end && ( *psz_string == '\t' || *psz_string == ' ' ); + psz_string++ ); + + /* read all digits */ + psz_item = psz_string; + while ( psz_string < end && *psz_string >= '0' && *psz_string <= '9' ) + { + psz_string++; + } + if ( *psz_item >= '0' && *psz_item <= '9' && *psz_string == ',' ) + { + *psz_string = '\0'; + *pi_duration = atoi(psz_item); + } + else + { + return; + } + if ( psz_string < end ) /* continue parsing if possible */ + { + psz_string++; + } + + /* read the author */ + char *pos; + /* parse the author until unescaped comma is reached */ + psz_item = pos = psz_string; + while( psz_string < end && *psz_string != ',' ) + { + if( *psz_string == '\\' ) + psz_string++; /* Skip escape character */ + *pos++ = *psz_string++; + } + *pos = '\0'; /* terminate the item */ + *ppsz_author = psz_item; + + if( psz_string < end ) /* continue parsing if possible */ + psz_string++; + /* the title doesn't need to be escaped */ + *ppsz_name = psz_string; + + return; +} + diff --git a/modules/misc/playlist/m3u.c b/modules/misc/playlist/m3u.c index 3ac0a1f627..c383be6624 100644 --- a/modules/misc/playlist/m3u.c +++ b/modules/misc/playlist/m3u.c @@ -68,17 +68,47 @@ int Export_M3U( vlc_object_t *p_this ) _("Meta-information"), _("Artist") ); if( psz_author && *psz_author ) { - fprintf( p_export->p_file, "#EXTINF:%i,%s - %s\n", - (int)(p_playlist->pp_items[i]->input.i_duration/1000000), - psz_author, p_playlist->pp_items[i]->input.psz_name ); + /* the author must be escaped if it contains a comma */ + char *p_src; short i_cnt; + /* so count the commas or backslash */ + for( i_cnt = 0, p_src = psz_author; *p_src; p_src++ ) + if(*p_src == ',' || *p_src == '\\' ) + i_cnt++; + /* Is there a comma ? */ + if( i_cnt ) + { + char *psz_escaped=NULL; + char *p_dst; + psz_escaped = (char *)malloc( ( strlen( psz_author ) + + i_cnt + 1 ) * sizeof( char ) ); + if( !psz_escaped ) + return VLC_ENOMEM; + /* copy the string and escape every comma with backslash */ + for( p_src=psz_author, p_dst=psz_escaped; *p_src; + p_src++, p_dst++ ) + { + if( *p_src == ',' || *p_src == '\\' ) + *p_dst++ = '\\'; + *p_dst = *p_src; + } + *p_dst = '\0'; + free( psz_author); + psz_author = psz_escaped; + } + fprintf( p_export->p_file, "#EXTINF:%i,%s,%s\n", + (int)(p_playlist->pp_items[i]->input.i_duration/1000000), + psz_author, + p_playlist->pp_items[i]->input.psz_name ); } else { - fprintf( p_export->p_file, "#EXTINF:%i,%s\n", - (int)(p_playlist->pp_items[i]->input.i_duration/1000000), + /* write EXTINF without author */ + fprintf( p_export->p_file, "#EXTINF:%i,,%s\n", + (int)(p_playlist->pp_items[i]->input.i_duration/1000000), p_playlist->pp_items[i]->input.psz_name ); } - free(psz_author); + if( psz_author ) + free( psz_author ); } /* VLC specific options */