X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fdemux%2Fplaylist%2Fitml.c;h=fc2fc00a1975de416c9383cffe44059df8a21be2;hb=9d016759c25f227281fb0af9a4ea82bf38328b6d;hp=19108f032323f4262ea0998cb5edd886aba3e628;hpb=918a6962f2223294a8818ef2c58fcc6d6f367528;p=vlc diff --git a/modules/demux/playlist/itml.c b/modules/demux/playlist/itml.c index 19108f0323..fc2fc00a19 100644 --- a/modules/demux/playlist/itml.c +++ b/modules/demux/playlist/itml.c @@ -31,12 +31,12 @@ #include #include +#include +#include +#include -#include "playlist.h" -#include "vlc_xml.h" -#include "vlc_strings.h" -#include "vlc_url.h" #include "itml.h" +#include "playlist.h" struct demux_sys_t { @@ -67,11 +67,11 @@ void Close_iTML( vlc_object_t *p_this ) */ int Demux( demux_t *p_demux ) { - xml_t *p_xml = NULL; + xml_t *p_xml; xml_reader_t *p_xml_reader = NULL; char *psz_name = NULL; - INIT_PLAYLIST_STUFF; + input_item_t *p_current_input = GetCurrentItem(p_demux); p_demux->p_sys->i_ntracks = 0; /* create new xml parser from stream */ @@ -101,17 +101,19 @@ int Demux( demux_t *p_demux ) goto end; } + input_item_node_t *p_subitems = input_item_node_Create( p_current_input ); xml_elem_hnd_t pl_elements[] = { {"dict", COMPLEX_CONTENT, {.cmplx = parse_plist_dict} } }; - parse_plist_node( p_demux, p_current_input, NULL, p_xml_reader, "plist", + parse_plist_node( p_demux, p_subitems, NULL, p_xml_reader, "plist", pl_elements ); + input_item_node_PostAndDelete( p_subitems ); - HANDLE_PLAY_AND_RELEASE; + vlc_gc_decref(p_current_input); end: free( psz_name ); if( p_xml_reader ) - xml_ReaderDelete( p_xml, p_xml_reader ); + xml_ReaderDelete( p_xml_reader ); if( p_xml ) xml_Delete( p_xml ); @@ -129,11 +131,14 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) /** * \brief parse the root node of the playlist */ -static bool parse_plist_node COMPLEX_INTERFACE +static bool parse_plist_node( demux_t *p_demux, input_item_node_t *p_input_node, + track_elem_t *p_track, xml_reader_t *p_xml_reader, + const char *psz_element, + xml_elem_hnd_t *p_handlers ) { VLC_UNUSED(p_track); VLC_UNUSED(psz_element); - char *psz_name = NULL; - char *psz_value = NULL; + char *psz_name; + char *psz_value; bool b_version_found = false; /* read all playlist attributes */ @@ -167,7 +172,7 @@ static bool parse_plist_node COMPLEX_INTERFACE if( !b_version_found ) msg_Warn( p_demux, " requires \"version\" attribute" ); - return parse_dict( p_demux, p_input_item, NULL, p_xml_reader, + return parse_dict( p_demux, p_input_node, NULL, p_xml_reader, "plist", p_handlers ); } @@ -175,127 +180,126 @@ static bool parse_plist_node COMPLEX_INTERFACE * \brief parse a * \param COMPLEX_INTERFACE */ -static bool parse_dict COMPLEX_INTERFACE +static bool parse_dict( demux_t *p_demux, input_item_node_t *p_input_node, + track_elem_t *p_track, xml_reader_t *p_xml_reader, + const char *psz_element, xml_elem_hnd_t *p_handlers ) { int i_node; char *psz_name = NULL; char *psz_value = NULL; char *psz_key = NULL; xml_elem_hnd_t *p_handler = NULL; + bool b_ret = false; while( xml_ReaderRead( p_xml_reader ) == 1 ) { i_node = xml_ReaderNodeType( p_xml_reader ); switch( i_node ) { - case XML_READER_NONE: - break; + case XML_READER_NONE: + break; - case XML_READER_STARTELEM: - /* element start tag */ - psz_name = xml_ReaderName( p_xml_reader ); - if( !psz_name || !*psz_name ) - { - msg_Err( p_demux, "invalid xml stream" ); - FREE_ATT_KEY(); - return false; - } - /* choose handler */ - for( p_handler = p_handlers; + case XML_READER_STARTELEM: + /* element start tag */ + psz_name = xml_ReaderName( p_xml_reader ); + if( !psz_name || !*psz_name ) + { + msg_Err( p_demux, "invalid xml stream" ); + goto end; + } + /* choose handler */ + for( p_handler = p_handlers; p_handler->name && strcmp( psz_name, p_handler->name ); p_handler++ ); - if( !p_handler->name ) + if( !p_handler->name ) + { + msg_Err( p_demux, "unexpected element <%s>", psz_name ); + goto end; + } + FREE_NAME(); + /* complex content is parsed in a separate function */ + if( p_handler->type == COMPLEX_CONTENT ) + { + if( p_handler->pf_handler.cmplx( p_demux, p_input_node, NULL, + p_xml_reader, p_handler->name, + NULL ) ) { - msg_Err( p_demux, "unexpected element <%s>", psz_name ); + p_handler = NULL; FREE_ATT_KEY(); - return false; } - FREE_NAME(); - /* complex content is parsed in a separate function */ - if( p_handler->type == COMPLEX_CONTENT ) - { - if( p_handler->pf_handler.cmplx( p_demux, - p_input_item, - NULL, - p_xml_reader, - p_handler->name, - NULL ) ) - { - p_handler = NULL; - FREE_ATT_KEY(); - } - else - { - FREE_ATT_KEY(); - return false; - } - } - break; + else + goto end; + } + break; - case XML_READER_TEXT: - /* simple element content */ - FREE_ATT(); - psz_value = xml_ReaderValue( p_xml_reader ); - if( !psz_value ) - { - msg_Err( p_demux, "invalid xml stream" ); - FREE_ATT_KEY(); - return false; - } - break; + case XML_READER_TEXT: + /* simple element content */ + free( psz_value ); + psz_value = xml_ReaderValue( p_xml_reader ); + if( !psz_value ) + { + msg_Err( p_demux, "invalid xml stream" ); + goto end; + } + break; - case XML_READER_ENDELEM: - /* element end tag */ - psz_name = xml_ReaderName( p_xml_reader ); - if( !psz_name ) - { - msg_Err( p_demux, "invalid xml stream" ); - FREE_ATT_KEY(); - return false; - } - /* leave if the current parent node is terminated */ - if( !strcmp( psz_name, psz_element ) ) - { - FREE_ATT_KEY(); - return true; - } - /* there MUST have been a start tag for that element name */ - if( !p_handler || !p_handler->name - || strcmp( p_handler->name, psz_name )) - { - msg_Err( p_demux, "there's no open element left for <%s>", - psz_name ); - FREE_ATT_KEY(); - return false; - } - /* special case: key */ - if( !strcmp( p_handler->name, "key" ) ) - { - psz_key = strdup( psz_value ); - } - /* call the simple handler */ - else if( p_handler->pf_handler.smpl ) - { - p_handler->pf_handler.smpl( p_track, psz_key, psz_value ); - } - FREE_ATT(); - p_handler = NULL; - break; - - default: - /* unknown/unexpected xml node */ - msg_Err( p_demux, "unexpected xml node %i", i_node ); - FREE_ATT_KEY(); - return false; + case XML_READER_ENDELEM: + /* element end tag */ + psz_name = xml_ReaderName( p_xml_reader ); + if( !psz_name ) + { + msg_Err( p_demux, "invalid xml stream" ); + goto end; + } + /* leave if the current parent node is terminated */ + if( !strcmp( psz_name, psz_element ) ) + { + b_ret = true; + goto end; + } + /* there MUST have been a start tag for that element name */ + if( !p_handler || !p_handler->name + || strcmp( p_handler->name, psz_name ) ) + { + msg_Err( p_demux, "there's no open element left for <%s>", + psz_name ); + goto end; + } + /* special case: key */ + if( !strcmp( p_handler->name, "key" ) ) + { + free( psz_key ); + psz_key = strdup( psz_value ); + } + /* call the simple handler */ + else if( p_handler->pf_handler.smpl ) + { + p_handler->pf_handler.smpl( p_track, psz_key, psz_value ); + } + FREE_ATT(); + p_handler = NULL; + break; + + default: + /* unknown/unexpected xml node */ + msg_Err( p_demux, "unexpected xml node %i", i_node ); + goto end; } FREE_NAME(); } msg_Err( p_demux, "unexpected end of xml data" ); - FREE_ATT_KEY(); - return false; + +end: + free( psz_name ); + free( psz_value ); + free( psz_key ); + return b_ret; } -static bool parse_plist_dict COMPLEX_INTERFACE +static bool parse_plist_dict( demux_t *p_demux, input_item_node_t *p_input_node, + track_elem_t *p_track, xml_reader_t *p_xml_reader, + const char *psz_element, + xml_elem_hnd_t *p_handlers ) { VLC_UNUSED(p_track); VLC_UNUSED(psz_element); VLC_UNUSED(p_handlers); xml_elem_hnd_t pl_elements[] = @@ -310,11 +314,14 @@ static bool parse_plist_dict COMPLEX_INTERFACE {NULL, UNKNOWN_CONTENT, {NULL} } }; - return parse_dict( p_demux, p_input_item, NULL, p_xml_reader, + return parse_dict( p_demux, p_input_node, NULL, p_xml_reader, "dict", pl_elements ); } -static bool parse_tracks_dict COMPLEX_INTERFACE +static bool parse_tracks_dict( demux_t *p_demux, input_item_node_t *p_input_node, + track_elem_t *p_track, xml_reader_t *p_xml_reader, + const char *psz_element, + xml_elem_hnd_t *p_handlers ) { VLC_UNUSED(p_track); VLC_UNUSED(psz_element); VLC_UNUSED(p_handlers); xml_elem_hnd_t tracks_elements[] = @@ -323,7 +330,7 @@ static bool parse_tracks_dict COMPLEX_INTERFACE {NULL, UNKNOWN_CONTENT, {NULL} } }; - parse_dict( p_demux, p_input_item, NULL, p_xml_reader, + parse_dict( p_demux, p_input_node, NULL, p_xml_reader, "dict", tracks_elements ); msg_Info( p_demux, "added %i tracks successfully", @@ -332,12 +339,14 @@ static bool parse_tracks_dict COMPLEX_INTERFACE return true; } -static bool parse_track_dict COMPLEX_INTERFACE +static bool parse_track_dict( demux_t *p_demux, input_item_node_t *p_input_node, + track_elem_t *p_track, xml_reader_t *p_xml_reader, + const char *psz_element, + xml_elem_hnd_t *p_handlers ) { VLC_UNUSED(psz_element); VLC_UNUSED(p_handlers); input_item_t *p_new_input = NULL; - int i_ret = -1; - char *psz_uri = NULL; + int i_ret; p_track = new_track(); xml_elem_hnd_t track_elements[] = @@ -351,7 +360,7 @@ static bool parse_track_dict COMPLEX_INTERFACE {NULL, UNKNOWN_CONTENT, {NULL} } }; - i_ret = parse_dict( p_demux, p_input_item, p_track, + i_ret = parse_dict( p_demux, p_input_node, p_track, p_xml_reader, "dict", track_elements ); msg_Dbg( p_demux, "name: %s, artist: %s, album: %s, genre: %s, trackNum: %s, location: %s", @@ -364,32 +373,15 @@ static bool parse_track_dict COMPLEX_INTERFACE return false; } - psz_uri = decode_URI_duplicate( p_track->location ); + msg_Info( p_demux, "Adding '%s'", p_track->location ); + p_new_input = input_item_New( p_demux, p_track->location, NULL ); + input_item_node_AppendItem( p_input_node, p_new_input ); - if( psz_uri ) - { - if( strlen( psz_uri ) > 17 && - !strncmp( psz_uri, "file://localhost/", 17 ) ) - { - /* remove 'localhost/' */ - memmove( psz_uri + 7, psz_uri + 17, strlen( psz_uri ) - 9 ); - msg_Info( p_demux, "Adding '%s'", psz_uri ); - - p_new_input = input_item_New( p_demux, psz_uri, NULL ); - input_item_AddSubItem( p_input_item, p_new_input ); - - /* add meta info */ - add_meta( p_new_input, p_track ); - vlc_gc_decref( p_new_input ); - - p_demux->p_sys->i_ntracks++; - } - else - { - msg_Err( p_demux, "Don't know how to handle %s", psz_uri ); - } - free( psz_uri ); - } + /* add meta info */ + add_meta( p_new_input, p_track ); + vlc_gc_decref( p_new_input ); + + p_demux->p_sys->i_ntracks++; free_track( p_track ); return i_ret; @@ -397,8 +389,8 @@ static bool parse_track_dict COMPLEX_INTERFACE static track_elem_t *new_track() { - track_elem_t *p_track = NULL; - p_track = (track_elem_t *)malloc( sizeof( track_elem_t ) ); + track_elem_t *p_track; + p_track = malloc( sizeof( track_elem_t ) ); if( p_track ) { p_track->name = NULL; @@ -428,7 +420,8 @@ static void free_track( track_elem_t *p_track ) free( p_track ); } -static bool save_data SIMPLE_INTERFACE +static bool save_data( track_elem_t *p_track, const char *psz_name, + char *psz_value) { /* exit if setting is impossible */ if( !psz_name || !psz_value || !p_track ) @@ -458,8 +451,7 @@ static bool save_data SIMPLE_INTERFACE /** * \brief handles the supported sub-elements */ -static bool add_meta( input_item_t *p_input_item, - track_elem_t *p_track ) +static bool add_meta( input_item_t *p_input_item, track_elem_t *p_track ) { /* exit if setting is impossible */ if( !p_input_item || !p_track ) @@ -480,9 +472,11 @@ static bool add_meta( input_item_t *p_input_item, /** * \brief skips complex element content that we can't manage */ -static bool skip_element COMPLEX_INTERFACE +static bool skip_element( demux_t *p_demux, input_item_node_t *p_input_node, + track_elem_t *p_track, xml_reader_t *p_xml_reader, + const char *psz_element, xml_elem_hnd_t *p_handlers ) { - VLC_UNUSED(p_demux); VLC_UNUSED(p_input_item); + VLC_UNUSED(p_demux); VLC_UNUSED(p_input_node); VLC_UNUSED(p_track); VLC_UNUSED(p_handlers); char *psz_endname;