X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fdemux%2Fplaylist%2Fasx.c;h=02e445b3bf31cc1dd367339538f550ec2a965d18;hb=78be7ca222d06e3cd85d4cc547573371507e7b07;hp=a3d44aeaa4ad800876921294f78ae9575d9d9f24;hpb=e8aa094f86e08a2c690555a0767763dcd63ffb90;p=vlc diff --git a/modules/demux/playlist/asx.c b/modules/demux/playlist/asx.c index a3d44aeaa4..02e445b3bf 100644 --- a/modules/demux/playlist/asx.c +++ b/modules/demux/playlist/asx.c @@ -27,24 +27,25 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#define _GNU_SOURCE -#include /* malloc(), free() */ -#include /* isspace() */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif -#include -#include +#include +#include -#include /* ENOMEM */ -#include "charset.h" +#include +#include #include "playlist.h" -#include "vlc_meta.h" +#include struct demux_sys_t { char *psz_prefix; char *psz_data; int64_t i_data_len; - vlc_bool_t b_utf8; + bool b_utf8; + bool b_skip_ads; }; /***************************************************************************** @@ -60,7 +61,7 @@ static int StoreString( demux_t *p_demux, char **ppsz_string, demux_sys_t *p_sys = p_demux->p_sys; unsigned len = psz_source_end - psz_source_start; - if( *ppsz_string ) free( *ppsz_string ); + free( *ppsz_string ); char *buf = *ppsz_string = malloc ((len * (1 + !p_sys->b_utf8)) + 1); if (buf == NULL) @@ -88,28 +89,116 @@ static int StoreString( demux_t *p_demux, char **ppsz_string, } *buf++ = '\0'; - buf = *ppsz_string = realloc (*ppsz_string, buf - *ppsz_string); + buf = realloc (*ppsz_string, buf - *ppsz_string); + if( buf ) + *ppsz_string = buf; } return VLC_SUCCESS; } +static char *SkipBlanks(char *s, size_t i_strlen ) +{ + while( i_strlen > 0 ) { + switch( *s ) + { + case ' ': + case '\t': + case '\r': + case '\n': + --i_strlen; + ++s; + break; + default: + i_strlen = 0; + } + } + return s; +} + +static int ParseTime(char *s, size_t i_strlen) +{ + // need to parse hour:minutes:sec.fraction string + int result = 0; + int val; + const char *end = s + i_strlen; + // skip leading spaces if any + s = SkipBlanks(s, i_strlen); + + val = 0; + while( (s < end) && isdigit(*s) ) + { + int newval = val*10 + (*s - '0'); + if( newval < val ) + { + // overflow + val = 0; + break; + } + val = newval; + ++s; + } + result = val; + s = SkipBlanks(s, end-s); + if( *s == ':' ) + { + ++s; + s = SkipBlanks(s, end-s); + result = result * 60; + val = 0; + while( (s < end) && isdigit(*s) ) + { + int newval = val*10 + (*s - '0'); + if( newval < val ) + { + // overflow + val = 0; + break; + } + val = newval; + ++s; + } + result += val; + s = SkipBlanks(s, end-s); + if( *s == ':' ) + { + ++s; + s = SkipBlanks(s, end-s); + result = result * 60; + val = 0; + while( (s < end) && isdigit(*s) ) + { + int newval = val*10 + (*s - '0'); + if( newval < val ) + { + // overflow + val = 0; + break; + } + val = newval; + ++s; + } + result += val; + // TODO: one day, we may need to parse fraction for sub-second resolution + } + } + return result; +} + /***************************************************************************** * Import_ASX: main import function *****************************************************************************/ -int E_(Import_ASX)( vlc_object_t *p_this ) +int Import_ASX( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t *)p_this; - uint8_t *p_peek, *p_peek_stop; + const uint8_t *p_peek; CHECK_PEEK( p_peek, 10 ); - p_peek_stop = p_peek+6; - - // skip over possible leading empty lines - while( (p_peek < p_peek_stop) && (*p_peek == '\n' || *p_peek == '\r')) ++p_peek; + // skip over possible leading empty lines and empty spaces + p_peek = (uint8_t *)SkipBlanks((char *)p_peek, 6); - if( POKE( p_peek, "p_sys->psz_prefix = E_(FindPrefix)( p_demux ); + p_demux->p_sys->psz_prefix = FindPrefix( p_demux ); p_demux->p_sys->psz_data = NULL; p_demux->p_sys->i_data_len = -1; - p_demux->p_sys->b_utf8 = VLC_FALSE; + p_demux->p_sys->b_utf8 = false; + p_demux->p_sys->b_skip_ads = + var_InheritBool( p_demux, "playlist-skip-ads" ); return VLC_SUCCESS; } @@ -128,13 +219,13 @@ int E_(Import_ASX)( vlc_object_t *p_this ) /***************************************************************************** * Deactivate: frees unused data *****************************************************************************/ -void E_(Close_ASX)( vlc_object_t *p_this ) +void Close_ASX( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t *)p_this; demux_sys_t *p_sys = p_demux->p_sys; - if( p_sys->psz_prefix ) free( p_sys->psz_prefix ); - if( p_sys->psz_data ) free( p_sys->psz_data ); + free( p_sys->psz_prefix ); + free( p_sys->psz_data ); free( p_sys ); } @@ -143,33 +234,35 @@ static int Demux( demux_t *p_demux ) demux_sys_t *p_sys = p_demux->p_sys; char *psz_parse = NULL; char *psz_backup = NULL; - vlc_bool_t b_entry = VLC_FALSE; - input_item_t *p_input; - INIT_PLAYLIST_STUFF; + bool b_entry = false; + input_item_t *p_current_input = GetCurrentItem(p_demux); /* init txt */ if( p_sys->i_data_len < 0 ) { int64_t i_pos = 0; - p_sys->i_data_len = stream_Size( p_demux->s ) +1; /* This is a cheat to prevent unnecessary realloc */ - if( p_sys->i_data_len <= 0 && p_sys->i_data_len < 16384 ) p_sys->i_data_len = 1024; - p_sys->psz_data = malloc( p_sys->i_data_len * sizeof(char) +1); - + p_sys->i_data_len = stream_Size( p_demux->s ) + 1; /* This is a cheat to prevent unnecessary realloc */ + if( p_sys->i_data_len <= 0 || p_sys->i_data_len > 16384 ) p_sys->i_data_len = 1024; + p_sys->psz_data = xmalloc( p_sys->i_data_len +1); + /* load the complete file */ for( ;; ) { int i_read = stream_Read( p_demux->s, &p_sys->psz_data[i_pos], p_sys->i_data_len - i_pos ); - p_sys->psz_data[i_read] = '\0'; - + p_sys->psz_data[i_pos + i_read] = '\0'; + if( i_read < p_sys->i_data_len - i_pos ) break; /* Done */ - + i_pos += i_read; - p_sys->i_data_len += 1024; - p_sys->psz_data = realloc( p_sys->psz_data, p_sys->i_data_len * sizeof( char * ) +1 ); + p_sys->i_data_len <<= 1 ; + p_sys->psz_data = xrealloc( p_sys->psz_data, + p_sys->i_data_len * sizeof( char * ) + 1 ); } - if( p_sys->i_data_len <= 0 ) return VLC_EGENERIC; + if( p_sys->i_data_len <= 0 ) return -1; } + input_item_node_t *p_subitems = input_item_node_Create( p_current_input ); + psz_parse = p_sys->psz_data; /* Find first element */ if( ( psz_parse = strcasestr( psz_parse, "" ); - while( ( psz_parse = strcasestr( psz_parse, "<" ) ) && psz_parse && *psz_parse ) + /* counter for single ad item */ + input_item_t *uniq_entry_ad_backup = NULL; + int i_inserted_entries = 0; + + while( psz_parse && ( psz_parse = strcasestr( psz_parse, "<" ) ) ) { if( !strncasecmp( psz_parse, "