#include <vlc_common.h>
#include <vlc_demux.h>
+#include <vlc_xml.h>
+#include <vlc_strings.h>
+#include <vlc_url.h>
-#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
{
*/
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 */
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 );
/**
* \brief parse the root node of the playlist
*/
-static bool parse_plist_node( demux_t *p_demux, input_item_t *p_input_item,
+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 */
if( !b_version_found )
msg_Warn( p_demux, "<plist> 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 );
}
* \brief parse a <dict>
* \param COMPLEX_INTERFACE
*/
-static bool parse_dict( demux_t *p_demux, input_item_t *p_input_item,
+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 )
{
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 <track> 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 <track> 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( demux_t *p_demux, input_item_t *p_input_item,
+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 )
{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( demux_t *p_demux, input_item_t *p_input_item,
+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 )
{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",
return true;
}
-static bool parse_track_dict( demux_t *p_demux, input_item_t *p_input_item,
+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[] =
{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",
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 );
+ /* add meta info */
+ add_meta( p_new_input, p_track );
+ vlc_gc_decref( p_new_input );
- 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 );
- }
+ p_demux->p_sys->i_ntracks++;
free_track( p_track );
return i_ret;
static track_elem_t *new_track()
{
- track_elem_t *p_track = NULL;
+ track_elem_t *p_track;
p_track = malloc( sizeof( track_elem_t ) );
if( p_track )
{
/**
* \brief skips complex element content that we can't manage
*/
-static bool skip_element( demux_t *p_demux, input_item_t *p_input_item,
+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;