[vlc-commits] playlist: m3u: rework parsing EXT Tags
Francois Cartegnie
git at videolan.org
Thu Mar 12 13:27:13 CET 2020
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Wed Mar 11 14:22:53 2020 +0100| [e19f71e95f4e6e3195e1658431f24ce2079f1fe5] | committer: Francois Cartegnie
playlist: m3u: rework parsing EXT Tags
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=e19f71e95f4e6e3195e1658431f24ce2079f1fe5
---
modules/demux/playlist/m3u.c | 178 ++++++++++++++++++++++++-------------------
1 file changed, 99 insertions(+), 79 deletions(-)
diff --git a/modules/demux/playlist/m3u.c b/modules/demux/playlist/m3u.c
index 0e6faf2adf..00ad624526 100644
--- a/modules/demux/playlist/m3u.c
+++ b/modules/demux/playlist/m3u.c
@@ -42,7 +42,6 @@
* Local prototypes
*****************************************************************************/
static int ReadDir( stream_t *, input_item_node_t * );
-static void parseEXTINF( char *psz_string, char **ppsz_artist, char **ppsz_name, int *pi_duration );
static bool ContainsURL(const uint8_t *, size_t);
static char *GuessEncoding (const char *str)
@@ -212,19 +211,66 @@ static bool ContainsURL(const uint8_t *p_peek, size_t i_peek)
return false;
}
+struct entry_meta_s
+{
+ char *psz_name;
+ char *psz_artist;
+ char *psz_album_art;
+ char *psz_mrl;
+ vlc_tick_t i_duration;
+ const char**ppsz_options;
+ int i_options;
+};
+
+static void entry_meta_Init( struct entry_meta_s *e )
+{
+ memset(e, 0, sizeof(*e));
+ e->i_duration = INPUT_DURATION_INDEFINITE;
+}
+
+static void entry_meta_Clean( struct entry_meta_s *e )
+{
+ free( e->psz_name );
+ free( e->psz_artist );
+ free( e->psz_album_art );
+ free( e->psz_mrl );
+ while( e->i_options-- ) free( (char*)e->ppsz_options[e->i_options] );
+}
+
+static void parseEXTINF( char *, char *(*)(const char *), struct entry_meta_s * );
+
+static int CreateEntry( input_item_node_t *p_node, const struct entry_meta_s *meta )
+{
+ if( !meta->psz_mrl )
+ return VLC_EGENERIC;
+
+ input_item_t *p_input =
+ input_item_NewExt( meta->psz_mrl, meta->psz_name, meta->i_duration,
+ ITEM_TYPE_UNKNOWN, ITEM_NET_UNKNOWN );
+ if( !p_input )
+ return VLC_EGENERIC;
+
+ input_item_AddOptions( p_input, meta->i_options, meta->ppsz_options, 0 );
+
+ if( meta->psz_artist )
+ input_item_SetArtist( p_input, meta->psz_artist );
+ if( meta->psz_name )
+ input_item_SetTitle( p_input, meta->psz_name );
+ if( meta->psz_album_art )
+ input_item_SetArtURL( p_input, meta->psz_album_art );
+
+ input_item_node_AppendItem( p_node, p_input );
+ input_item_Release( p_input );
+
+ return VLC_SUCCESS;
+}
+
static int ReadDir( stream_t *p_demux, input_item_node_t *p_subitems )
{
char *psz_line;
- char *psz_name = NULL;
- char *psz_artist = NULL;
- char *psz_album_art = NULL;
- int i_parsed_duration = 0;
- vlc_tick_t i_duration = INPUT_DURATION_INDEFINITE;
- const char**ppsz_options = NULL;
+ struct entry_meta_s meta;
+ entry_meta_Init( &meta );
char * (*pf_dup) (const char *) = p_demux->p_sys;
- int i_options = 0;
- bool b_cleanup = false;
- input_item_t *p_input;
psz_line = vlc_stream_ReadLine( p_demux->s );
while( psz_line )
@@ -243,21 +289,14 @@ static int ReadDir( stream_t *p_demux, input_item_node_t *p_subitems )
while( isspace( *psz_parse ) || *psz_parse == '#' )
psz_parse++;
- if( !*psz_parse ) goto error;
+ if( !*psz_parse ) goto nextline;
if( !strncasecmp( psz_parse, "EXTINF:", sizeof("EXTINF:") -1 ) )
{
/* Extended info */
psz_parse += sizeof("EXTINF:") - 1;
- FREENULL( psz_name );
- FREENULL( psz_artist );
- parseEXTINF( psz_parse, &psz_artist, &psz_name, &i_parsed_duration );
- if( i_parsed_duration >= 0 )
- i_duration = vlc_tick_from_sec( i_parsed_duration );
- if( psz_name )
- psz_name = pf_dup( psz_name );
- if( psz_artist )
- psz_artist = pf_dup( psz_artist );
+ meta.i_duration = INPUT_DURATION_INDEFINITE;
+ parseEXTINF( psz_parse, pf_dup, &meta );
}
else if( !strncasecmp( psz_parse, "EXTVLCOPT:",
sizeof("EXTVLCOPT:") -1 ) )
@@ -265,11 +304,11 @@ static int ReadDir( stream_t *p_demux, input_item_node_t *p_subitems )
/* VLC Option */
char *psz_option;
psz_parse += sizeof("EXTVLCOPT:") -1;
- if( !*psz_parse ) goto error;
+ if( !*psz_parse ) goto nextline;
psz_option = pf_dup( psz_parse );
if( psz_option )
- TAB_APPEND( i_options, ppsz_options, psz_option );
+ TAB_APPEND( meta.i_options, meta.ppsz_options, psz_option );
}
/* Special case for jamendo which provide the albumart */
else if( !strncasecmp( psz_parse, "EXTALBUMARTURL:",
@@ -278,8 +317,8 @@ static int ReadDir( stream_t *p_demux, input_item_node_t *p_subitems )
psz_parse += sizeof( "EXTALBUMARTURL:" ) - 1;
if( *psz_parse )
{
- free( psz_album_art );
- psz_album_art = pf_dup( psz_parse );
+ free( meta.psz_album_art );
+ meta.psz_album_art = pf_dup( psz_parse );
}
}
}
@@ -289,69 +328,38 @@ static int ReadDir( stream_t *p_demux, input_item_node_t *p_subitems )
}
else if( *psz_parse )
{
- char *psz_mrl;
-
psz_parse = pf_dup( psz_parse );
- if( !psz_name && psz_parse )
+ if( !meta.psz_name && psz_parse )
/* Use filename as name for relative entries */
- psz_name = strdup( psz_parse );
-
- psz_mrl = ProcessMRL( psz_parse, p_demux->psz_url );
+ meta.psz_name = strdup( psz_parse );
- b_cleanup = true;
- if( !psz_mrl )
- {
- free( psz_parse );
- goto error;
- }
-
- p_input = input_item_NewExt( psz_mrl, psz_name, i_duration,
- ITEM_TYPE_UNKNOWN, ITEM_NET_UNKNOWN );
+ meta.psz_mrl = ProcessMRL( psz_parse, p_demux->psz_url );
free( psz_parse );
- free( psz_mrl );
-
- if( !p_input )
- goto error;
- input_item_AddOptions( p_input, i_options, ppsz_options, 0 );
- if( !EMPTY_STR(psz_artist) )
- input_item_SetArtist( p_input, psz_artist );
- if( !EMPTY_STR(psz_name) ) input_item_SetTitle( p_input, psz_name );
- if( psz_album_art )
- input_item_SetArtURL( p_input, psz_album_art );
+ CreateEntry( p_subitems, &meta );
- input_item_node_AppendItem( p_subitems, p_input );
- input_item_Release( p_input );
+ /* Cleanup state after entry */
+ entry_meta_Clean( &meta );
+ entry_meta_Init( &meta );
}
- error:
-
+ nextline:
/* Fetch another line */
free( psz_line );
psz_line = vlc_stream_ReadLine( p_demux->s );
- if( !psz_line ) b_cleanup = true;
-
- if( b_cleanup )
+ if( !psz_line )
{
/* Cleanup state */
- while( i_options-- ) free( (char*)ppsz_options[i_options] );
- FREENULL( ppsz_options );
- i_options = 0;
- FREENULL( psz_name );
- FREENULL( psz_artist );
- FREENULL( psz_album_art );
- i_parsed_duration = 0;
- i_duration = INPUT_DURATION_INDEFINITE;
-
- b_cleanup = false;
+ entry_meta_Clean( &meta );
+ entry_meta_Init( &meta );
}
}
return VLC_SUCCESS; /* Needed for correct operation of go back */
}
-static void parseEXTINFTitle(char *psz_string,
- char **ppsz_artist,
- char **ppsz_name)
+static void parseEXTINFTitle( char *psz_string,
+ char *(*pf_dup) (const char *),
+ struct entry_meta_s *meta )
{
char *psz_item = strstr( psz_string, " - " );
@@ -360,8 +368,10 @@ static void parseEXTINFTitle(char *psz_string,
{
/* *** "EXTINF:time,artist - name" */
*psz_item = '\0';
- *ppsz_artist = psz_string;
- *ppsz_name = psz_item + 3; /* points directly after ' - ' */
+ if( *psz_string )
+ meta->psz_artist = pf_dup( psz_string );
+ if( psz_item[3] )
+ meta->psz_name = pf_dup( &psz_item[3] ); /* points directly after ' - ' */
return;
}
@@ -370,7 +380,8 @@ static void parseEXTINFTitle(char *psz_string,
{
/* *** "EXTINF:time,,name" */
psz_string++;
- *ppsz_name = psz_string;
+ if( *psz_string )
+ meta->psz_name = pf_dup( psz_string );
return;
}
@@ -380,21 +391,28 @@ static void parseEXTINFTitle(char *psz_string,
{
/* *** "EXTINF:time,artist,name" */
*psz_string = '\0';
- *ppsz_artist = psz_item;
- *ppsz_name = psz_string+1;
+ if( *psz_item )
+ meta->psz_artist = pf_dup( psz_item );
+ if( psz_string[1] )
+ meta->psz_name = pf_dup( &psz_string[1] );
}
else
{
/* *** "EXTINF:time,name" */
- *ppsz_name = psz_item;
+ if( *psz_item )
+ meta->psz_name = pf_dup( psz_item );
}
}
-static void parseEXTINF( char *psz_string, char **ppsz_artist,
- char **ppsz_name, int *pi_duration )
+static void parseEXTINF( char *psz_string,
+ char *(*pf_dup)(const char *),
+ struct entry_meta_s *meta )
{
char *end = psz_string + strlen( psz_string );
+ FREENULL( meta->psz_name );
+ FREENULL( meta->psz_artist );
+
/* strip leading whitespaces */
while( psz_string < end && isspace( *psz_string ) )
psz_string++;
@@ -405,10 +423,12 @@ static void parseEXTINF( char *psz_string, char **ppsz_artist,
{
*psz_comma = '\0'; /* Split strings */
if( ++psz_comma < end )
- parseEXTINFTitle( psz_comma, ppsz_artist, ppsz_name );
+ parseEXTINFTitle( psz_comma, pf_dup, meta );
}
/* Parse duration */
- *pi_duration = strtol( psz_string, NULL, 10 );
+ long i_parsed_duration = strtol( psz_string, NULL, 10 );
+ if( i_parsed_duration > 0 )
+ meta->i_duration = vlc_tick_from_sec( i_parsed_duration );
}
More information about the vlc-commits
mailing list