]> git.sesse.net Git - vlc/commitdiff
ALL: Improvements in the M3U output and parser. Patch by Daniel Stränger.
authorChristophe Mutricy <xtophe@videolan.org>
Fri, 12 Aug 2005 14:20:06 +0000 (14:20 +0000)
committerChristophe Mutricy <xtophe@videolan.org>
Fri, 12 Aug 2005 14:20:06 +0000 (14:20 +0000)
     (Put both artist and name, protect comma with \ )

THANKS
modules/demux/playlist/m3u.c
modules/misc/playlist/m3u.c

diff --git a/THANKS b/THANKS
index 5f60d5ba3befbeaf16b1200fbd171d2ea254b5ef..064e0fd71c6cbaf23994ef9bf565dffc224232f1 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -31,6 +31,7 @@ Christopher Johnson <cjohnson at mint.net> - Qt fix in vlc.spec
 Colin Simmonds <colin_simmonds at Mac.lover.org> - compile fix for Mac OS X
 Damian Ivereigh <damian at cisco.com> - ac3dec uninitialized data structure fix
 Damien Fouilleul <damien.fouilleul at laposte.net> - DirectShow input improvements
+Daniel Stränger <vlc at schmaller d0t de> - M3U improvements
 David Kennedy <dkennedy at tinytoad.com> - X11 fullscreen patch
 David Weber <david_weber at gmx.de> - Mac OS X interface design & graphics (v0.5.0)
 Davor Orel <syntheticamac at yahoo.it> - Mac OS X icons
index dcd3d037c25a88304e465bc566138d92983dfa03..5d48cbacde99a8dd1f8641a2e6343015aab57202 100644 (file)
@@ -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;
+}
+
index 3ac0a1f62789aca8a29e66746bb7415bcd74f74b..c383be6624f963e919db60a13e842293c0097103 100644 (file)
@@ -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 */