static int Demux( demux_t *p_demux ) { int i_ret = -1; xml_t *p_xml; xml_reader_t *p_xml_reader = NULL; char *psz_elname = NULL; input_item_t *p_input; char *psz_mrl = NULL, *psz_title = NULL, *psz_genre = NULL; char *psz_now = NULL, *psz_listeners = NULL, *psz_bitrate = NULL; input_item_node_t *p_subitems = NULL; input_item_t *p_current_input = GetCurrentItem(p_demux); p_xml = xml_Create( p_demux ); if( !p_xml ) goto end; psz_elname = stream_ReadLine( p_demux->s ); free( psz_elname ); psz_elname = NULL; p_xml_reader = xml_ReaderCreate( p_xml, p_demux->s ); if( !p_xml_reader ) goto end; /* xml */ /* check root node */ if( xml_ReaderRead( p_xml_reader ) != 1 ) { msg_Err( p_demux, "invalid file (no root node)" ); goto end; } if( xml_ReaderNodeType( p_xml_reader ) != XML_READER_STARTELEM || ( psz_elname = xml_ReaderName( p_xml_reader ) ) == NULL || strcmp( psz_elname, "WinampXML" ) ) { msg_Err( p_demux, "invalid root node %i, %s", xml_ReaderNodeType( p_xml_reader ), psz_elname ); goto end; } FREENULL( psz_elname ); /* root node should not have any attributes, and should only * contain the "playlist node */ /* Skip until 1st child node */ while( (i_ret = xml_ReaderRead( p_xml_reader )) == 1 && xml_ReaderNodeType( p_xml_reader ) != XML_READER_STARTELEM ); if( i_ret != 1 ) { msg_Err( p_demux, "invalid file (no child node)" ); goto end; } if( ( psz_elname = xml_ReaderName( p_xml_reader ) ) == NULL || strcmp( psz_elname, "playlist" ) ) { msg_Err( p_demux, "invalid child node %s", psz_elname ); goto end; } FREENULL( psz_elname ); // Read the attributes while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) { char *psz_name = xml_ReaderName( p_xml_reader ); char *psz_value = xml_ReaderValue( p_xml_reader ); if( !psz_name || !psz_value ) { free( psz_name ); free( psz_value ); goto end; } if( !strcmp( psz_name, "num_entries" ) ) { msg_Dbg( p_demux, "playlist has %d entries", atoi(psz_value) ); } else if( !strcmp( psz_name, "label" ) ) { input_item_SetName( p_current_input, psz_value ); } else { msg_Warn( p_demux, "stray attribute %s with value %s in element" " 'playlist'", psz_name, psz_value ); } free( psz_name ); free( psz_value ); } p_subitems = input_item_node_Create( p_current_input ); while( (i_ret = xml_ReaderRead( p_xml_reader )) == 1 ) { // Get the node type switch( xml_ReaderNodeType( p_xml_reader ) ) { // Error case -1: goto end; case XML_READER_STARTELEM: { // Read the element name free( psz_elname ); psz_elname = xml_ReaderName( p_xml_reader ); if( !psz_elname ) goto end; // Read the attributes while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) { char *psz_name = xml_ReaderName( p_xml_reader ); char *psz_value = xml_ReaderValue( p_xml_reader ); if( !psz_name || !psz_value ) { free( psz_name ); free( psz_value ); goto end; } if( !strcmp( psz_elname, "entry" ) && !strcmp( psz_name, "Playstring" ) ) { psz_mrl = psz_value; } else { msg_Warn( p_demux, "unexpected attribute %s in element %s", psz_name, psz_elname ); free( psz_value ); } free( psz_name ); } break; } case XML_READER_TEXT: { char *psz_text = xml_ReaderValue( p_xml_reader ); if( IsWhitespace( psz_text ) ) { free( psz_text ); break; } if( !strcmp( psz_elname, "Name" ) ) { psz_title = psz_text; } else if( !strcmp( psz_elname, "Genre" ) ) { psz_genre = psz_text; } else if( !strcmp( psz_elname, "Nowplaying" ) ) { psz_now = psz_text; } else if( !strcmp( psz_elname, "Listeners" ) ) { psz_listeners = psz_text; } else if( !strcmp( psz_elname, "Bitrate" ) ) { psz_bitrate = psz_text; } else if( !strcmp( psz_elname, "" ) ) { free( psz_text ); } else { msg_Warn( p_demux, "unexpected text in element '%s'", psz_elname ); free( psz_text ); } break; } // End element case XML_READER_ENDELEM: { // Read the element name free( psz_elname ); psz_elname = xml_ReaderName( p_xml_reader ); if( !psz_elname ) goto end; if( !strcmp( psz_elname, "entry" ) ) { p_input = input_item_New( p_demux, psz_mrl, psz_title ); if( psz_now ) input_item_SetNowPlaying( p_input, psz_now ); if( psz_genre ) input_item_SetGenre( p_input, psz_genre ); if( psz_listeners ) msg_Err( p_demux, "Unsupported meta listeners" ); if( psz_bitrate ) msg_Err( p_demux, "Unsupported meta bitrate" ); input_item_node_AppendItem( p_subitems, p_input ); vlc_gc_decref( p_input ); FREENULL( psz_title ); FREENULL( psz_mrl ); FREENULL( psz_genre ); FREENULL( psz_bitrate ); FREENULL( psz_listeners ); FREENULL( psz_now ); } free( psz_elname ); psz_elname = strdup( "" ); break; } } } if( i_ret != 0 ) { msg_Warn( p_demux, "error while parsing data" ); i_ret = 0; /* Needed for correct operation of go back */ } end: free( psz_elname ); if( p_subitems ) input_item_node_PostAndDelete( p_subitems ); vlc_gc_decref( p_current_input ); if( p_xml_reader ) xml_ReaderDelete( p_xml, p_xml_reader ); if( p_xml ) xml_Delete( p_xml ); return i_ret; }
/** * \brief demuxer function for XSPF parsing */ int Demux( demux_t *p_demux ) { int i_ret = 1; xml_t *p_xml = NULL; xml_reader_t *p_xml_reader = NULL; char *psz_name = NULL; INIT_PLAYLIST_STUFF; p_demux->p_sys->pp_tracklist = NULL; p_demux->p_sys->i_tracklist_entries = 0; p_demux->p_sys->i_track_id = -1; p_demux->p_sys->psz_base = NULL; /* create new xml parser from stream */ p_xml = xml_Create( p_demux ); if( !p_xml ) i_ret = -1; else { p_xml_reader = xml_ReaderCreate( p_xml, p_demux->s ); if( !p_xml_reader ) i_ret = -1; } /* locating the root node */ if( i_ret == 1 ) { do { if( xml_ReaderRead( p_xml_reader ) != 1 ) { msg_Err( p_demux, "can't read xml stream" ); i_ret = -1; } } while( i_ret == VLC_SUCCESS && xml_ReaderNodeType( p_xml_reader ) != XML_READER_STARTELEM ); } /* checking root node name */ if( i_ret == 1 ) { psz_name = xml_ReaderName( p_xml_reader ); if( !psz_name || strcmp( psz_name, "playlist" ) ) { msg_Err( p_demux, "invalid root node name: %s", psz_name ); i_ret = -1; } FREE_NAME(); } if( i_ret == 1 ) i_ret = parse_playlist_node( p_demux, p_current_input, p_xml_reader, "playlist" ) ? 0 : -1; int i; for( i = 0 ; i < p_demux->p_sys->i_tracklist_entries ; i++ ) { input_item_t *p_new_input = p_demux->p_sys->pp_tracklist[i]; if( p_new_input ) { input_item_AddSubItem( p_current_input, p_new_input ); } } HANDLE_PLAY_AND_RELEASE; if( p_xml_reader ) xml_ReaderDelete( p_xml, p_xml_reader ); if( p_xml ) xml_Delete( p_xml ); return i_ret; /* Needed for correct operation of go back */ }
/** * \brief demuxer function for XSPF parsing */ int Demux( demux_t *p_demux ) { int i_ret = -1; xml_t *p_xml = NULL; xml_reader_t *p_xml_reader = NULL; char *psz_name = NULL; input_item_t *p_current_input = GetCurrentItem(p_demux); p_demux->p_sys->pp_tracklist = NULL; p_demux->p_sys->i_tracklist_entries = 0; p_demux->p_sys->i_track_id = -1; p_demux->p_sys->psz_base = NULL; /* create new xml parser from stream */ p_xml = xml_Create( p_demux ); if( !p_xml ) goto end; p_xml_reader = xml_ReaderCreate( p_xml, p_demux->s ); if( !p_xml_reader ) goto end; /* locating the root node */ do { if( xml_ReaderRead( p_xml_reader ) != 1 ) { msg_Err( p_demux, "can't read xml stream" ); goto end; } } while( xml_ReaderNodeType( p_xml_reader ) != XML_READER_STARTELEM ); /* checking root node name */ psz_name = xml_ReaderName( p_xml_reader ); if( !psz_name || strcmp( psz_name, "playlist" ) ) { msg_Err( p_demux, "invalid root node name: %s", psz_name ); free( psz_name ); goto end; } free( psz_name ); i_ret = parse_playlist_node( p_demux, p_current_input, p_xml_reader, "playlist" ) ? 0 : -1; for( int i = 0 ; i < p_demux->p_sys->i_tracklist_entries ; i++ ) { input_item_t *p_new_input = p_demux->p_sys->pp_tracklist[i]; if( p_new_input ) { input_item_AddSubItem( p_current_input, p_new_input ); } } end: vlc_gc_decref(p_current_input); if( p_xml_reader ) xml_ReaderDelete( p_xml, p_xml_reader ); if( p_xml ) xml_Delete( p_xml ); return i_ret; /* Needed for correct operation of go back */ }
/**************************************************************************** * Parse the rss feed ***************************************************************************/ static bool ParseFeed( filter_t *p_filter, xml_reader_t *p_xml_reader, rss_feed_t *p_feed ) { VLC_UNUSED(p_filter); char *psz_eltname = NULL; bool b_is_item = false; bool b_is_image = false; int i_item = 0; while( xml_ReaderRead( p_xml_reader ) == 1 ) { switch( xml_ReaderNodeType( p_xml_reader ) ) { // Error case -1: goto end; case XML_READER_STARTELEM: free( psz_eltname ); psz_eltname = xml_ReaderName( p_xml_reader ); if( !psz_eltname ) goto end; #ifdef RSS_DEBUG msg_Dbg( p_filter, "element name: %s", psz_eltname ); #endif /* rss or atom */ if( !strcmp( psz_eltname, "item" ) || !strcmp( psz_eltname, "entry" ) ) { b_is_item = true; p_feed->i_items++; p_feed->p_items = xrealloc( p_feed->p_items, p_feed->i_items * sizeof( rss_item_t ) ); p_feed->p_items[p_feed->i_items-1].psz_title = NULL; p_feed->p_items[p_feed->i_items-1].psz_description = NULL; p_feed->p_items[p_feed->i_items-1].psz_link = NULL; } /* rss */ else if( !strcmp( psz_eltname, "image" ) ) { b_is_image = true; } /* atom */ else if( !strcmp( psz_eltname, "link" ) ) { char *psz_href = NULL; char *psz_rel = NULL; while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) { char *psz_name = xml_ReaderName( p_xml_reader ); char *psz_value = xml_ReaderValue( p_xml_reader ); if( !strcmp( psz_name, "rel" ) ) { free( psz_rel ); psz_rel = psz_value; } else if( !strcmp( psz_name, "href" ) ) { free( psz_href ); psz_href = psz_value; } else { free( psz_value ); } free( psz_name ); } /* "rel" and "href" must be defined */ if( psz_rel && psz_href ) { if( !strcmp( psz_rel, "alternate" ) && !b_is_item && !b_is_image && !p_feed->psz_link ) { p_feed->psz_link = psz_href; } /* this isn't in the rfc but i found some ... */ else if( ( !strcmp( psz_rel, "logo" ) || !strcmp( psz_rel, "icon" ) ) && !b_is_item && !b_is_image && !p_feed->psz_image ) { p_feed->psz_image = psz_href; } else { free( psz_href ); } } else { free( psz_href ); } free( psz_rel ); } break; case XML_READER_ENDELEM: free( psz_eltname ); psz_eltname = xml_ReaderName( p_xml_reader ); if( !psz_eltname ) goto end; #ifdef RSS_DEBUG msg_Dbg( p_filter, "element end : %s", psz_eltname ); #endif /* rss or atom */ if( !strcmp( psz_eltname, "item" ) || !strcmp( psz_eltname, "entry" ) ) { b_is_item = false; i_item++; } /* rss */ else if( !strcmp( psz_eltname, "image" ) ) { b_is_image = false; } FREENULL( psz_eltname ); break; case XML_READER_TEXT: { if( !psz_eltname ) break; char *psz_eltvalue = xml_ReaderValue( p_xml_reader ); if( !psz_eltvalue ) goto end; char *psz_clean = removeWhiteChars( psz_eltvalue ); free( psz_eltvalue ); psz_eltvalue = psz_clean; #ifdef RSS_DEBUG msg_Dbg( p_filter, " text : <%s>", psz_eltvalue ); #endif /* Is it an item ? */ if( b_is_item ) { rss_item_t *p_item = p_feed->p_items+i_item; /* rss/atom */ if( !strcmp( psz_eltname, "title" ) && !p_item->psz_title ) { p_item->psz_title = psz_eltvalue; } else if( !strcmp( psz_eltname, "link" ) /* rss */ && !p_item->psz_link ) { p_item->psz_link = psz_eltvalue; } /* rss/atom */ else if( ( !strcmp( psz_eltname, "description" ) || !strcmp( psz_eltname, "summary" ) ) && !p_item->psz_description ) { p_item->psz_description = psz_eltvalue; } else { free( psz_eltvalue ); } } /* Is it an image ? */ else if( b_is_image ) { if( !strcmp( psz_eltname, "url" ) && !p_feed->psz_image ) p_feed->psz_image = psz_eltvalue; else free( psz_eltvalue ); } else { /* rss/atom */ if( !strcmp( psz_eltname, "title" ) && !p_feed->psz_title ) { p_feed->psz_title = psz_eltvalue; } /* rss */ else if( !strcmp( psz_eltname, "link" ) && !p_feed->psz_link ) { p_feed->psz_link = psz_eltvalue; } /* rss ad atom */ else if( ( !strcmp( psz_eltname, "description" ) || !strcmp( psz_eltname, "subtitle" ) ) && !p_feed->psz_description ) { p_feed->psz_description = psz_eltvalue; } /* rss */ else if( ( !strcmp( psz_eltname, "logo" ) || !strcmp( psz_eltname, "icon" ) ) && !p_feed->psz_image ) { p_feed->psz_image = psz_eltvalue; } else { free( psz_eltvalue ); } } break; } } } free( psz_eltname ); return true; end: free( psz_eltname ); return false; }
static void ParseUSFHeaderTags( decoder_t *p_dec, xml_reader_t *p_xml_reader ) { decoder_sys_t *p_sys = p_dec->p_sys; char *psz_node; ssa_style_t *p_ssa_style = NULL; int i_style_level = 0; int i_metadata_level = 0; while ( xml_ReaderRead( p_xml_reader ) == 1 ) { switch ( xml_ReaderNodeType( p_xml_reader ) ) { case XML_READER_TEXT: case XML_READER_NONE: break; case XML_READER_ENDELEM: psz_node = xml_ReaderName( p_xml_reader ); if( !psz_node ) break; switch (i_style_level) { case 0: if( !strcasecmp( "metadata", psz_node ) && (i_metadata_level == 1) ) { i_metadata_level--; } break; case 1: if( !strcasecmp( "styles", psz_node ) ) { i_style_level--; } break; case 2: if( !strcasecmp( "style", psz_node ) ) { TAB_APPEND( p_sys->i_ssa_styles, p_sys->pp_ssa_styles, p_ssa_style ); p_ssa_style = NULL; i_style_level--; } break; } free( psz_node ); break; case XML_READER_STARTELEM: psz_node = xml_ReaderName( p_xml_reader ); if( !psz_node ) break; if( !strcasecmp( "metadata", psz_node ) && (i_style_level == 0) ) { i_metadata_level++; } else if( !strcasecmp( "resolution", psz_node ) && ( i_metadata_level == 1) ) { while ( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) { char *psz_name = xml_ReaderName ( p_xml_reader ); char *psz_value = xml_ReaderValue ( p_xml_reader ); if( psz_name && psz_value ) { if( !strcasecmp( "x", psz_name ) ) p_sys->i_original_width = atoi( psz_value ); else if( !strcasecmp( "y", psz_name ) ) p_sys->i_original_height = atoi( psz_value ); } free( psz_name ); free( psz_value ); } } else if( !strcasecmp( "styles", psz_node ) && (i_style_level == 0) ) { i_style_level++; } else if( !strcasecmp( "style", psz_node ) && (i_style_level == 1) ) { i_style_level++; p_ssa_style = calloc( 1, sizeof(ssa_style_t) ); if( !p_ssa_style ) { free( psz_node ); return; } /* All styles are supposed to default to Default, and then * one or more settings are over-ridden. * At the moment this only effects styles defined AFTER * Default in the XML */ int i; for( i = 0; i < p_sys->i_ssa_styles; i++ ) { if( !strcasecmp( p_sys->pp_ssa_styles[i]->psz_stylename, "Default" ) ) { ssa_style_t *p_default_style = p_sys->pp_ssa_styles[i]; memcpy( p_ssa_style, p_default_style, sizeof( ssa_style_t ) ); //FIXME: Make font_style a pointer. Actually we double copy some data here, // we use text_style_Copy to avoid copying psz_fontname, though . text_style_Copy( &p_ssa_style->font_style, &p_default_style->font_style ); p_ssa_style->psz_stylename = NULL; } } while ( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) { char *psz_name = xml_ReaderName ( p_xml_reader ); char *psz_value = xml_ReaderValue ( p_xml_reader ); if( psz_name && psz_value ) { if( !strcasecmp( "name", psz_name ) ) p_ssa_style->psz_stylename = strdup( psz_value ); } free( psz_name ); free( psz_value ); } } else if( !strcasecmp( "fontstyle", psz_node ) && (i_style_level == 2) ) { while ( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) { char *psz_name = xml_ReaderName ( p_xml_reader ); char *psz_value = xml_ReaderValue ( p_xml_reader ); if( psz_name && psz_value ) { if( !strcasecmp( "face", psz_name ) ) { free( p_ssa_style->font_style.psz_fontname ); p_ssa_style->font_style.psz_fontname = strdup( psz_value ); } else if( !strcasecmp( "size", psz_name ) ) { if( ( *psz_value == '+' ) || ( *psz_value == '-' ) ) { int i_value = atoi( psz_value ); if( ( i_value >= -5 ) && ( i_value <= 5 ) ) p_ssa_style->font_style.i_font_size += ( i_value * p_ssa_style->font_style.i_font_size ) / 10; else if( i_value < -5 ) p_ssa_style->font_style.i_font_size = - i_value; else if( i_value > 5 ) p_ssa_style->font_style.i_font_size = i_value; } else p_ssa_style->font_style.i_font_size = atoi( psz_value ); } else if( !strcasecmp( "italic", psz_name ) ) { if( !strcasecmp( "yes", psz_value )) p_ssa_style->font_style.i_style_flags |= STYLE_ITALIC; else p_ssa_style->font_style.i_style_flags &= ~STYLE_ITALIC; } else if( !strcasecmp( "weight", psz_name ) ) { if( !strcasecmp( "bold", psz_value )) p_ssa_style->font_style.i_style_flags |= STYLE_BOLD; else p_ssa_style->font_style.i_style_flags &= ~STYLE_BOLD; } else if( !strcasecmp( "underline", psz_name ) ) { if( !strcasecmp( "yes", psz_value )) p_ssa_style->font_style.i_style_flags |= STYLE_UNDERLINE; else p_ssa_style->font_style.i_style_flags &= ~STYLE_UNDERLINE; } else if( !strcasecmp( "color", psz_name ) ) { if( *psz_value == '#' ) { unsigned long col = strtol(psz_value+1, NULL, 16); p_ssa_style->font_style.i_font_color = (col & 0x00ffffff); p_ssa_style->font_style.i_font_alpha = (col >> 24) & 0xff; } } else if( !strcasecmp( "outline-color", psz_name ) ) { if( *psz_value == '#' ) { unsigned long col = strtol(psz_value+1, NULL, 16); p_ssa_style->font_style.i_outline_color = (col & 0x00ffffff); p_ssa_style->font_style.i_outline_alpha = (col >> 24) & 0xff; } } else if( !strcasecmp( "outline-level", psz_name ) ) { p_ssa_style->font_style.i_outline_width = atoi( psz_value ); } else if( !strcasecmp( "shadow-color", psz_name ) ) { if( *psz_value == '#' ) { unsigned long col = strtol(psz_value+1, NULL, 16); p_ssa_style->font_style.i_shadow_color = (col & 0x00ffffff); p_ssa_style->font_style.i_shadow_alpha = (col >> 24) & 0xff; } } else if( !strcasecmp( "shadow-level", psz_name ) )