Beispiel #1
0
/**
 * \brief parse the root node of the playlist
 */
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);
    const char *attr, *value;
    bool b_version_found = false;

    /* read all playlist attributes */
    while( (attr = xml_ReaderNextAttr( p_xml_reader, &value )) != NULL )
    {
        /* attribute: version */
        if( !strcmp( attr, "version" ) )
        {
            b_version_found = true;
            if( strcmp( value, "1.0" ) )
                msg_Warn( p_demux, "unsupported iTunes Media Library version" );
        }
        /* unknown attribute */
        else
            msg_Warn( p_demux, "invalid <plist> attribute:\"%s\"", attr );
    }

    /* attribute version is mandatory !!! */
    if( !b_version_found )
        msg_Warn( p_demux, "<plist> requires \"version\" attribute" );

    return parse_dict( p_demux, p_input_node, NULL, p_xml_reader,
                       "plist", p_handlers );
}
Beispiel #2
0
/* <genrelist>
 *   <genre name="the name"></genre>
 *   ...
 * </genrelist>
 **/
static int DemuxGenre( demux_t *p_demux, xml_reader_t *p_xml_reader,
                       input_item_node_t *p_input_node )
{
    const char *node;
    char *psz_name = NULL; /* genre name */
    int type;

    while( (type = xml_ReaderNextNode( p_xml_reader, &node )) > 0 )
    {
        switch( type )
        {
            case XML_READER_STARTELEM:
            {
                if( !strcmp( node, "genre" ) )
                {
                    // Read the attributes
                    const char *name, *value;
                    while( (name = xml_ReaderNextAttr( p_xml_reader, &value )) )
                    {
                        if( !strcmp( name, "name" ) )
                        {
                            free(psz_name);
                            psz_name = strdup( value );
                        }
                        else
                            msg_Warn( p_demux,
                                      "unexpected attribute %s in <%s>",
                                      name, node );
                    }
                }
                break;
            }

            case XML_READER_ENDELEM:
                if( !strcmp( node, "genre" ) && psz_name != NULL )
                {
                    char* psz_mrl;

                    if( asprintf( &psz_mrl, SHOUTCAST_BASE_URL "?genre=%s",
                                  psz_name ) != -1 )
                    {
                        input_item_t *p_input;
                        vlc_xml_decode( psz_mrl );
                        p_input = input_item_New( psz_mrl, psz_name );
                        input_item_CopyOptions( p_input_node->p_item, p_input );
                        free( psz_mrl );
                        input_item_node_AppendItem( p_input_node, p_input );
                        vlc_gc_decref( p_input );
                    }
                    FREENULL( psz_name );
                }
                break;
        }
    }

    free( psz_name );
    return 0;
}
Beispiel #3
0
tt_node_t * tt_node_New( xml_reader_t* reader, tt_node_t* p_parent, const char* psz_node_name )
{
    tt_node_t *p_node = calloc( 1, sizeof( *p_node ) );
    if( !p_node )
        return NULL;

    p_node->i_type = TT_NODE_TYPE_ELEMENT;
    p_node->psz_node_name = strdup( psz_node_name );
    if( unlikely( p_node->psz_node_name == NULL ) )
    {
        free( p_node );
        return NULL;
    }
    vlc_dictionary_init( &p_node->attr_dict, 0 );
    tt_time_Init( &p_node->timings.begin );
    tt_time_Init( &p_node->timings.end );
    tt_time_Init( &p_node->timings.dur );
    p_node->p_parent = p_parent;
    if( p_parent )
        tt_node_ParentAddChild( p_parent, (tt_basenode_t *) p_node );

    const char* psz_value = NULL;
    for( const char* psz_key = xml_ReaderNextAttr( reader, &psz_value );
         psz_key != NULL;
         psz_key = xml_ReaderNextAttr( reader, &psz_value ) )
    {
        char *psz_val = strdup( psz_value );
        if( psz_val )
        {
            vlc_dictionary_insert( &p_node->attr_dict, psz_key, psz_val );

            if( !strcasecmp( psz_key, "begin" ) )
                p_node->timings.begin = tt_ParseTime( psz_val );
            else if( ! strcasecmp( psz_key, "end" ) )
                p_node->timings.end = tt_ParseTime( psz_val );
            else if( ! strcasecmp( psz_key, "dur" ) )
                p_node->timings.dur = tt_ParseTime( psz_val );
            else if( ! strcasecmp( psz_key, "timeContainer" ) )
                p_node->timings.i_type = strcmp( psz_val, "seq" ) ? TT_TIMINGS_PARALLEL
                                                                  : TT_TIMINGS_SEQUENTIAL;
        }
    }
    return p_node;
}
static int ParseSkins2Info( addons_finder_t *p_finder, stream_t *p_stream,
                            char **ppsz_title, char **ppsz_source )
{
    const char *p_node;
    int i_current_node_type;
    bool b_done = false;

    xml_reader_t *p_xml_reader = xml_ReaderCreate( p_finder, p_stream );
    if( !p_xml_reader ) return VLC_EGENERIC;

    if( xml_ReaderNextNode( p_xml_reader, &p_node ) != XML_READER_STARTELEM )
    {
        msg_Err( p_finder, "invalid xml file" );
        goto error;
    }

    if ( strcmp( p_node, "Theme") )
    {
        msg_Err( p_finder, "unsupported XML data format" );
        goto error;
    }

    while( !b_done && (i_current_node_type = xml_ReaderNextNode( p_xml_reader, &p_node )) > 0 )
    {
        switch( i_current_node_type )
        {
        case XML_READER_STARTELEM:
        {
            if ( !strcmp( p_node, "ThemeInfo" ) )
            {
                const char *attr, *value;
                while( (attr = xml_ReaderNextAttr( p_xml_reader, &value )) )
                {
                    if ( !strcmp( attr, "name" ) )
                        *ppsz_title = strdup( value );
                    else if ( !strcmp( attr, "webpage" ) )
                        *ppsz_source = strdup( value );
                }
                b_done = true;
            }
            break;
        }

        default:
            break;
        }
    }

    xml_ReaderDelete( p_xml_reader );
    return ( b_done ) ? VLC_SUCCESS : VLC_EGENERIC;

error:
    xml_ReaderDelete( p_xml_reader );
    return VLC_EGENERIC;
}
Beispiel #5
0
static void ParseTTMLStyle( decoder_t *p_dec, xml_reader_t* p_reader )
{
    decoder_sys_t* p_sys = p_dec->p_sys;
    ttml_style_t *p_ttml_style = NULL;
    ttml_style_t *p_base_style = NULL;

    p_ttml_style = calloc( 1, sizeof(ttml_style_t) );

    if ( unlikely( !p_ttml_style ) )
        return ;
    p_ttml_style->font_style = text_style_Create( STYLE_NO_DEFAULTS );
    if( unlikely( !p_ttml_style->font_style ) )
    {
        free( p_ttml_style );
        return ;
    }

    const char *attr, *val;

    while( (attr = xml_ReaderNextAttr( p_reader, &val ) ) )
    {
        if ( !strcasecmp( attr, "style" ) )
        {
            for( size_t i = 0; i < p_sys->i_styles; i++ )
            {
                if( !strcasecmp( p_sys->pp_styles[i]->psz_styleid, val ) )
                {
                    p_base_style = p_sys->pp_styles[i];
                    break;
                }
            }
        }
        else if ( !strcasecmp( "xml:id", attr ) )
        {
            free( p_ttml_style->psz_styleid );
            p_ttml_style->psz_styleid = strdup( val );
        }
        else if ( !strcasecmp ( "tts:fontFamily", attr ) )
        {
            free( p_ttml_style->font_style->psz_fontname );
            p_ttml_style->font_style->psz_fontname = strdup( val );
        }
        else if ( !strcasecmp( "tts:fontSize", attr ) )
        {
            p_ttml_style->font_style->i_font_size  = atoi( val );
        }
        else if ( !strcasecmp( "tts:color", attr ) )
        {
            unsigned int i_color = vlc_html_color( val, NULL );
            p_ttml_style->font_style->i_font_color = (i_color & 0xffffff);
            p_ttml_style->font_style->i_font_alpha = (i_color & 0xFF000000) >> 24;
            p_ttml_style->font_style->i_features |= STYLE_HAS_FONT_COLOR | STYLE_HAS_FONT_ALPHA;
        }
        else if ( !strcasecmp( "tts:backgroundColor", attr ) )
Beispiel #6
0
static int vlclua_xml_reader_next_attr( lua_State *L )
{
    xml_reader_t *p_reader = *(xml_reader_t**)luaL_checkudata( L, 1, "xml_reader" );
    const char *psz_value;
    const char *psz_name = xml_ReaderNextAttr( p_reader, &psz_value );
    if( !psz_name )
        return 0;

    lua_pushstring( L, psz_name );
    lua_pushstring( L, psz_value );
    return 2;
}
Beispiel #7
0
static void read_head( demux_t* p_demux, input_item_t* p_input )
{
    demux_sys_t* p_sys = p_demux->p_sys;
    const char* psz_name;
    int i_type;

    do
    {
        i_type = xml_ReaderNextNode( p_sys->p_reader, &psz_name );
        if ( !strcasecmp( psz_name, "meta" ) )
        {
            char* psz_attribute_name = NULL;
            char* psz_attribute_value = NULL;
            while (!psz_attribute_name || !psz_attribute_value)
            {
                const char* psz_attr = NULL;
                const char* psz_val = NULL;
                psz_attr = xml_ReaderNextAttr( p_sys->p_reader, &psz_val );
                if ( !psz_attr || !psz_val )
                    break;
                if ( !strcasecmp( psz_attr, "name" ) )
                    psz_attribute_name = strdup( psz_val );
                else if ( !strcasecmp( psz_attr, "content" ) )
                    psz_attribute_value = strdup( psz_val );
            }
            if ( psz_attribute_name && psz_attribute_value )
            {
                if ( !strcasecmp( psz_attribute_name, "TotalDuration" ) )
                    input_item_SetDuration( p_input, atoll( psz_attribute_value ) );
                else if ( !strcasecmp( psz_attribute_name, "Author" ) )
                    input_item_SetPublisher( p_input, psz_attribute_value );
                else if ( !strcasecmp( psz_attribute_name, "Rating" ) )
                    input_item_SetRating( p_input, psz_attribute_value );
                else if ( !strcasecmp( psz_attribute_name, "Genre" ) )
                    input_item_SetGenre( p_input, psz_attribute_value );
            }
            free( psz_attribute_name );
            free( psz_attribute_value );
        }
        else if ( !strcasecmp( psz_name, "title" ) )
        {
            const char* psz_title;
            int i_type = xml_ReaderNextNode( p_sys->p_reader, &psz_title );
            if ( i_type == XML_READER_TEXT && psz_title != NULL )
                input_item_SetTitle( p_input, psz_title );
        }
    } while ( i_type != XML_READER_ENDELEM || strcasecmp( psz_name, "head" ) );
}
Beispiel #8
0
bool XMLParser::parse()
{
    const char *node;
    int type;

    if( !m_pReader ) return false;

    m_errors = false;

    while( (type = xml_ReaderNextNode( m_pReader, &node )) > 0 )
    {
        if( m_errors ) return false;

        switch( type )
        {
            case XML_READER_STARTELEM:
            {
                // Read the attributes
                AttrList_t attributes;
                const char *name, *value;
                while( (name = xml_ReaderNextAttr( m_pReader, &value )) != NULL )
                    attributes[strdup(name)] = strdup(value);

                handleBeginElement( node, attributes );

                map<const char*, const char*, ltstr> ::iterator it =
                    attributes.begin();
                while( it != attributes.end() )
                {
                    free( (char *)it->first );
                    free( (char *)it->second );
                    ++it;
                }
                break;
            }

            // End element
            case XML_READER_ENDELEM:
            {
                handleEndElement( node );
                break;
            }
        }
    }
    return (type == 0 && !m_errors );
}
Beispiel #9
0
static void read_body( demux_t* p_demux, input_item_node_t* p_node )
{
    demux_sys_t* p_sys = p_demux->p_sys;
    const char* psz_name;
    int i_type;

    i_type = xml_ReaderNextNode( p_sys->p_reader, &psz_name );
    if ( i_type != XML_READER_STARTELEM || strcasecmp( psz_name, "seq" ) )
    {
        msg_Err( p_demux, "Expected opening <seq> tag. Got <%s> with type %d", psz_name, i_type );
        return;
    }

    do
    {
        i_type = xml_ReaderNextNode( p_sys->p_reader, &psz_name );
        if ( !strcasecmp( psz_name, "media" ) )
        {
            const char* psz_attr = NULL;
            const char* psz_val = NULL;
            while ((psz_attr = xml_ReaderNextAttr( p_sys->p_reader, &psz_val )))
            {
                if ( !psz_val )
                    continue;
                if (!strcasecmp( psz_attr, "src" ) )
                {
                    char* mrl = ProcessMRL( psz_val, p_sys->psz_prefix );
                    if ( unlikely( !mrl ) )
                        return;
                    input_item_t* p_item = input_item_NewExt( mrl, NULL, 0, NULL, 0, -1 );
                    if ( likely( p_item ) )
                    {
                        input_item_node_AppendItem( p_node, p_item );
                        input_item_Release( p_item );
                    }
                    free( mrl );
                }
            }
        }
    } while ( i_type != XML_READER_ENDELEM || strcasecmp( psz_name, "seq" ) );

    i_type = xml_ReaderNextNode( p_sys->p_reader, &psz_name );
    if ( i_type != XML_READER_ENDELEM || strcasecmp( psz_name, "body" ) )
        msg_Err( p_demux, "Expected closing <body> tag. Got: <%s> with type %d", psz_name, i_type );
}
Beispiel #10
0
/* "specs" : http://phobos.apple.com/static/iTunesRSS.html */
static int ReadDir( stream_t *p_demux, input_item_node_t *p_subitems )
{
    bool b_item = false;
    bool b_image = false;

    xml_reader_t *p_xml_reader;
    char *psz_elname = NULL;
    char *psz_item_mrl = NULL;
    char *psz_item_size = NULL;
    char *psz_item_type = NULL;
    char *psz_item_name = NULL;
    char *psz_item_date = NULL;
    char *psz_item_author = NULL;
    char *psz_item_category = NULL;
    char *psz_item_duration = NULL;
    char *psz_item_keywords = NULL;
    char *psz_item_subtitle = NULL;
    char *psz_item_summary = NULL;
    char *psz_art_url = NULL;
    const char *node;
    int i_type;
    input_item_t *p_input;

    input_item_t *p_current_input = GetCurrentItem(p_demux);

    p_xml_reader = xml_ReaderCreate( p_demux, p_demux->s );
    if( !p_xml_reader )
        goto error;

    /* xml */
    /* check root node */
    if( xml_ReaderNextNode( p_xml_reader, &node ) != XML_READER_STARTELEM )
    {
        msg_Err( p_demux, "invalid file (no root node)" );
        goto error;
    }

    if( strcmp( node, "rss" ) )
    {
        msg_Err( p_demux, "invalid root node <%s>", node );
        goto error;
    }

    while( (i_type = xml_ReaderNextNode( p_xml_reader, &node )) > 0 )
    {
        switch( i_type )
        {
            case XML_READER_STARTELEM:
            {
                free( psz_elname );
                psz_elname = strdup( node );
                if( unlikely(!psz_elname) )
                    goto error;

                if( !strcmp( node, "item" ) )
                    b_item = true;
                else if( !strcmp( node, "image" ) )
                    b_image = true;

                // Read the attributes
                const char *attr, *value;
                while( (attr = xml_ReaderNextAttr( p_xml_reader, &value )) )
                {
                    if( !strcmp( node, "enclosure" ) )
                    {
                        char **p = NULL;
                        if( !strcmp( attr, "url" ) )
                            p = &psz_item_mrl;
                        else if( !strcmp( attr, "length" ) )
                            p = &psz_item_size;
                        else if( !strcmp( attr, "type" ) )
                            p = &psz_item_type;
                        if( p != NULL )
                        {
                            free( *p );
                            *p = strdup( value );
                        }
                        else
                            msg_Dbg( p_demux,"unhandled attribute %s in <%s>",
                                     attr, node );
                    }
                    else
                        msg_Dbg( p_demux,"unhandled attribute %s in <%s>",
                                 attr, node );
                }
                break;
            }

            case XML_READER_TEXT:
            {
                if(!psz_elname) break;

                /* item specific meta data */
                if( b_item )
                {
                    char **p;

                    if( !strcmp( psz_elname, "title" ) )
                        p = &psz_item_name;
                    else if( !strcmp( psz_elname, "itunes:author" ) ||
                             !strcmp( psz_elname, "author" ) )
                        /* <author> isn't standard iTunes podcast stuff */
                        p = &psz_item_author;
                    else if( !strcmp( psz_elname, "itunes:summary" ) ||
                             !strcmp( psz_elname, "description" ) )
                        /* <description> isn't standard iTunes podcast stuff */
                        p = &psz_item_summary;
                    else if( !strcmp( psz_elname, "pubDate" ) )
                        p = &psz_item_date;
                    else if( !strcmp( psz_elname, "itunes:category" ) )
                        p = &psz_item_category;
                    else if( !strcmp( psz_elname, "itunes:duration" ) )
                        p = &psz_item_duration;
                    else if( !strcmp( psz_elname, "itunes:keywords" ) )
                        p = &psz_item_keywords;
                    else if( !strcmp( psz_elname, "itunes:subtitle" ) )
                        p = &psz_item_subtitle;
                    else
                        break;

                    free( *p );
                    *p = strdup( node );
                }
                /* toplevel meta data */
                else if( !b_image )
                {
                    if( !strcmp( psz_elname, "title" ) )
                        input_item_SetName( p_current_input, node );
#define ADD_GINFO( info, name ) \
    else if( !strcmp( psz_elname, name ) ) \
        input_item_AddInfo( p_current_input, _("Podcast Info"), \
                            info, "%s", node );
                    ADD_GINFO( _("Podcast Link"), "link" )
                    ADD_GINFO( _("Podcast Copyright"), "copyright" )
                    ADD_GINFO( _("Podcast Category"), "itunes:category" )
                    ADD_GINFO( _("Podcast Keywords"), "itunes:keywords" )
                    ADD_GINFO( _("Podcast Subtitle"), "itunes:subtitle" )
#undef ADD_GINFO
                    else if( !strcmp( psz_elname, "itunes:summary" ) ||
                             !strcmp( psz_elname, "description" ) )
                    { /* <description> isn't standard iTunes podcast stuff */
                        input_item_AddInfo( p_current_input,
                            _( "Podcast Info" ), _( "Podcast Summary" ),
                            "%s", node );
                    }
                }
                else
                {
                    if( !strcmp( psz_elname, "url" ) && *node )
                    {
                        free( psz_art_url );
                        psz_art_url = strdup( node );
                    }
                    else
                        msg_Dbg( p_demux, "unhandled text in element <%s>",
                                 psz_elname );
                }
                break;
            }

            // End element
            case XML_READER_ENDELEM:
            {
                FREENULL( psz_elname );

                if( !strcmp( node, "item" ) )
                {
                    if( psz_item_mrl == NULL )
                    {
                        if (psz_item_name)
                            msg_Warn( p_demux, "invalid XML item, skipping %s",
                                      psz_item_name );
                        else
                            msg_Warn( p_demux, "invalid XML item, skipped" );
                        FREENULL( psz_item_name );
                        FREENULL( psz_item_size );
                        FREENULL( psz_item_type );
                        FREENULL( psz_item_date );
                        FREENULL( psz_item_author );
                        FREENULL( psz_item_category );
                        FREENULL( psz_item_duration );
                        FREENULL( psz_item_keywords );
                        FREENULL( psz_item_subtitle );
                        FREENULL( psz_item_summary );
                        FREENULL( psz_art_url );
                        FREENULL( psz_elname );
                        continue;
                    }

                    vlc_xml_decode( psz_item_mrl );
                    vlc_xml_decode( psz_item_name );
                    p_input = input_item_New( psz_item_mrl, psz_item_name );
                    FREENULL( psz_item_mrl );
                    FREENULL( psz_item_name );

                    if( p_input == NULL )
                        break; /* FIXME: meta data memory leaks? */

                    /* Set the duration if available */
                    if( psz_item_duration )
                        p_input->i_duration = strTimeToMTime( psz_item_duration );

#define ADD_INFO( info, field ) \
    if( field ) { \
        input_item_AddInfo( p_input, _( "Podcast Info" ), (info), "%s", \
                            (field) ); \
        FREENULL( field ); }
                    ADD_INFO( _("Podcast Publication Date"), psz_item_date  );
                    ADD_INFO( _("Podcast Author"), psz_item_author );
                    ADD_INFO( _("Podcast Subcategory"), psz_item_category );
                    ADD_INFO( _("Podcast Duration"), psz_item_duration );
                    ADD_INFO( _("Podcast Keywords"), psz_item_keywords );
                    ADD_INFO( _("Podcast Subtitle"), psz_item_subtitle );
                    ADD_INFO( _("Podcast Summary"), psz_item_summary );
                    ADD_INFO( _("Podcast Type"), psz_item_type );
#undef ADD_INFO

                    /* Add the global art url to this item, if any */
                    if( psz_art_url )
                    {
                        vlc_xml_decode( psz_art_url );
                        input_item_SetArtURL( p_input, psz_art_url );
                    }

                    if( psz_item_size )
                    {
                        input_item_AddInfo( p_input,
                                                _( "Podcast Info" ),
                                                _( "Podcast Size" ),
                                                _("%s bytes"),
                                                psz_item_size );
                        FREENULL( psz_item_size );
                    }
                    input_item_node_AppendItem( p_subitems, p_input );
                    input_item_Release( p_input );
                    b_item = false;
                }
                else if( !strcmp( node, "image" ) )
                {
                    b_image = false;
                }
                break;
            }
        }
    }
Beispiel #11
0
/****************************************************************************
 * 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;
}
Beispiel #12
0
static void ProcessEntry( int *pi_n_entry, xml_reader_t *p_xml_reader,
                         input_item_node_t *p_subitems,
                         input_item_t *p_current_input, char *psz_prefix )
{
    const char *psz_node = NULL;
    const char *psz_txt = NULL;
    int i_type;

    char *psz_title = NULL;
    char *psz_artist = NULL;
    char *psz_copyright = NULL;
    char *psz_moreinfo = NULL;
    char *psz_description = NULL;
    char *psz_name = NULL;
    char *psz_mrl = NULL;
    char *psz_href = NULL;

    input_item_t *p_entry = NULL;

    int i_options;
    mtime_t i_start = 0;
    mtime_t i_duration = 0;
    char *ppsz_options[2];

    do
    {
        i_type = xml_ReaderNextNode( p_xml_reader, &psz_node );

        if( i_type == XML_READER_STARTELEM )
        {
            /* Metadata Node */
            if( !strncasecmp( psz_node, "TITLE", 5 ) )
                ReadElement( p_xml_reader, &psz_title );
            else if( !strncasecmp( psz_node, "AUTHOR", 6 ) )
                ReadElement( p_xml_reader, &psz_artist );
            else if( !strncasecmp( psz_node, "COPYRIGHT", 9 ) )
                ReadElement( p_xml_reader, &psz_copyright );
            else if( !strncasecmp( psz_node,"MOREINFO", 8 ) )
            {
                do
                {
                    psz_txt = xml_ReaderNextAttr( p_xml_reader, &psz_node );
                }
                while(psz_txt && strncasecmp( psz_txt, "HREF", 4 ) );

                if( !psz_txt )
                    ReadElement( p_xml_reader, &psz_moreinfo );
                else
                    psz_moreinfo = strdup( psz_node );
                resolve_xml_special_chars( psz_moreinfo );
            }
            else if( !strncasecmp( psz_node, "ABSTRACT", 8 ) )
                ReadElement( p_xml_reader, &psz_description );
            else if( !strncasecmp( psz_node, "DURATION", 8 ) )
                i_duration = ParseTime( p_xml_reader );
            else if( !strncasecmp( psz_node, "STARTTIME", 9 ) )
                i_start = ParseTime( p_xml_reader );
            else
            /* Reference Node */
            /* All ref node will be converted into an entry */
            if( !strncasecmp( psz_node, "REF", 3 ) )
            {
                *pi_n_entry = *pi_n_entry + 1;

                if( !psz_title )
                    psz_title = input_item_GetTitle( p_current_input );
                if( !psz_artist )
                    psz_artist = input_item_GetArtist( p_current_input );
                if( !psz_copyright )
                    psz_copyright = input_item_GetCopyright( p_current_input );
                if( !psz_description )
                    psz_description = input_item_GetDescription( p_current_input );

                do
                {
                    psz_txt = xml_ReaderNextAttr( p_xml_reader, &psz_node );
                }
                while( strncasecmp( psz_txt, "HREF", 4) );
                psz_href = strdup( psz_node );

                if( asprintf( &psz_name, "%d. %s", *pi_n_entry, psz_title ) == -1)
                    psz_name = strdup( psz_title );
                resolve_xml_special_chars( psz_href );
                psz_mrl = ProcessMRL( psz_href, psz_prefix );

                /* Add Time information */
                i_options = 0;
                if( i_start )
                {
                    if( asprintf( ppsz_options, ":start-time=%d" ,(int) i_start/1000000 ) != -1)
                        i_options++;
                }
                if( i_duration)
                {
                    if( asprintf( ppsz_options + i_options, ":stop-time=%d",
                                (int) (i_start+i_duration)/1000000 ) != -1)
                        i_options++;
                }

                /* Create the input item */
                p_entry = input_item_NewExt( psz_mrl, psz_name, i_options,
                        (const char* const*) ppsz_options, VLC_INPUT_OPTION_TRUSTED, i_duration );
                input_item_CopyOptions( p_current_input, p_entry );

                /* Add the metadata */
                if( psz_name )
                    input_item_SetTitle( p_entry, psz_name );
                if( psz_artist )
                    input_item_SetArtist( p_entry, psz_artist );
                if( psz_copyright )
                    input_item_SetCopyright( p_entry, psz_copyright );
                if( psz_moreinfo )
                    input_item_SetURL( p_entry, psz_moreinfo );
                if( psz_description )
                    input_item_SetDescription( p_entry, psz_description );
                if( i_duration > 0)
                    input_item_SetDuration( p_entry, i_duration );

                input_item_node_AppendItem( p_subitems, p_entry );

                while( i_options )
                    free( ppsz_options[--i_options] );
                free( psz_name );
                free( psz_mrl );
            }
        }
    }
    while( i_type != XML_READER_ENDELEM || strncasecmp( psz_node, "ENTRY", 5 ) );

    free( psz_href );
    free( psz_title );
    free( psz_artist );
    free( psz_copyright );
    free( psz_moreinfo );
    free( psz_description );
}
static int LoadCatalog( addons_finder_t *p_finder )
{
    char *psz_path;
    char * psz_userdir = config_GetUserDir( VLC_DATA_DIR );
    if ( !psz_userdir ) return VLC_ENOMEM;

    if ( asprintf( &psz_path, "%s%s", psz_userdir, ADDONS_CATALOG ) < 1 )
    {
        free( psz_userdir );
        return VLC_ENOMEM;
    }
    free( psz_userdir );

    addon_entry_t *p_entry = NULL;
    const char *p_node;
    int i_current_node_type;
    int i_ret = VLC_SUCCESS;

    /* attr */
    const char *attr, *value;

    /* temp reading */
    char *psz_filename = NULL;
    int i_filetype = -1;

    struct stat stat_;
    if ( vlc_stat( psz_path, &stat_ ) )
    {
        free( psz_path );
        return VLC_EGENERIC;
    }

    char *psz_catalog_uri = vlc_path2uri( psz_path, "file" );
    free( psz_path );
    if ( !psz_catalog_uri )
        return VLC_EGENERIC;

    stream_t *p_stream = stream_UrlNew( p_finder, psz_catalog_uri );
    free( psz_catalog_uri );
    if (! p_stream ) return VLC_EGENERIC;

    xml_reader_t *p_xml_reader = xml_ReaderCreate( p_finder, p_stream );
    if( !p_xml_reader )
    {
        stream_Delete( p_stream );
        return VLC_EGENERIC;
    }

    if( xml_ReaderNextNode( p_xml_reader, &p_node ) != XML_READER_STARTELEM )
    {
        msg_Err( p_finder, "invalid catalog" );
        i_ret = VLC_EGENERIC;
        goto end;
    }

    if ( strcmp( p_node, "videolan") )
    {
        msg_Err( p_finder, "unsupported catalog data format" );
        i_ret = VLC_EGENERIC;
        goto end;
    }

    while( (i_current_node_type = xml_ReaderNextNode( p_xml_reader, &p_node )) > 0 )
    {
        switch( i_current_node_type )
        {
        case XML_READER_STARTELEM:
        {
            if ( ! strcmp( p_node, "addon" ) )
            {
                if ( p_entry ) /* ?!? Unclosed tag */
                    addon_entry_Release( p_entry );

                p_entry = addon_entry_New();
                //p_entry->psz_source_module = strdup( ADDONS_MODULE_SHORTCUT );
                p_entry->e_flags = ADDON_MANAGEABLE;
                p_entry->e_state = ADDON_INSTALLED;

                while( (attr = xml_ReaderNextAttr( p_xml_reader, &value )) )
                {
                    if ( !strcmp( attr, "type" ) )
                    {
                        p_entry->e_type = ReadType( value );
                    }
                    else if ( !strcmp( attr, "id" ) )
                    {
                        addons_uuid_read( value, & p_entry->uuid );
                    }
                    else if ( !strcmp( attr, "downloads" ) )
                    {
                        p_entry->i_downloads = atoi( value );
                        if ( p_entry->i_downloads < 0 )
                            p_entry->i_downloads = 0;
                    }
                    else if ( !strcmp( attr, "score" ) )
                    {
                        p_entry->i_score = atoi( value );
                        if ( p_entry->i_score < 0 )
                            p_entry->i_score = 0;
                        else if ( p_entry->i_score > ADDON_MAX_SCORE )
                            p_entry->i_score = ADDON_MAX_SCORE;
                    }
                    else if ( !strcmp( attr, "source" ) )
                    {
                        p_entry->psz_source_module = strdup( value );
                    }
                    else if ( !strcmp( attr, "version" ) )
                    {
                        p_entry->psz_version = strdup( value );
                    }
                }

                break;
            }
            if ( !p_entry ) break;

            BINDNODE("name", p_entry->psz_name, TYPE_STRING)
            BINDNODE("archive", p_entry->psz_archive_uri, TYPE_STRING)
            BINDNODE("summary", p_entry->psz_summary, TYPE_STRING)
            BINDNODE("description", p_entry->psz_description, TYPE_STRING)
            BINDNODE("image", p_entry->psz_image_data, TYPE_STRING)
            BINDNODE("resource", psz_filename, TYPE_STRING)
            BINDNODE("creator", p_entry->psz_author, TYPE_STRING)
            BINDNODE("sourceurl", p_entry->psz_source_uri, TYPE_STRING)
            data_pointer.e_type = TYPE_NONE;

            if ( ! strcmp( p_node, "resource" ) )
            {
                while( (attr = xml_ReaderNextAttr( p_xml_reader, &value )) )
                {
                    if ( !strcmp( attr, "type" ) )
                    {
                        i_filetype = ReadType( value );
                    }
                }
            }

            break;
        }
        case XML_READER_TEXT:
            if ( data_pointer.e_type == TYPE_NONE || !p_entry ) break;
            if ( data_pointer.e_type == TYPE_STRING )
                *data_pointer.u_data.ppsz = strdup( p_node );
            else
            if ( data_pointer.e_type == TYPE_LONG )
                *data_pointer.u_data.pl = atol( p_node );
            else
            if ( data_pointer.e_type == TYPE_INTEGER )
                *data_pointer.u_data.pi = atoi( p_node );
            break;

        case XML_READER_ENDELEM:
            if ( !p_entry ) break;

            if ( ! strcmp( p_node, "addon" ) )
            {
                /* then append entry */
                ARRAY_APPEND( p_finder->entries, p_entry );
                p_entry = NULL;
            }

            if ( ! strcmp( p_node, "resource" ) )
            {
                if ( p_entry && psz_filename && i_filetype >= 0 )
                {
                    addon_file_t *p_file = malloc( sizeof(addon_file_t) );
                    p_file->e_filetype = i_filetype;
                    p_file->psz_filename = psz_filename;
                    p_file->psz_download_uri = NULL;
                    ARRAY_APPEND( p_entry->files, p_file );
                }
                /* reset temp */
                psz_filename = NULL;
                i_filetype = -1;
            }

            data_pointer.e_type = TYPE_NONE;
            break;

        default:
            break;
        }
    }

end:
   if ( p_entry ) /* ?!? Unclosed tag */
       addon_entry_Release( p_entry );
   xml_ReaderDelete( p_xml_reader );
   stream_Delete( p_stream );
   return i_ret;
}
Beispiel #14
0
static int ParseCategoriesInfo( addons_finder_t *p_finder, stream_t *p_stream )
{
    int i_num_entries_created = 0;

    const char *p_node;
    const char *attr, *value;
    int i_current_node_type;
    addon_entry_t *p_entry = NULL;

    xml_reader_t *p_xml_reader = xml_ReaderCreate( p_finder, p_stream );
    if( !p_xml_reader ) return 0;

    if( xml_ReaderNextNode( p_xml_reader, &p_node ) != XML_READER_STARTELEM )
    {
        msg_Err( p_finder, "invalid xml file" );
        goto end;
    }

    if ( strcmp( p_node, "videolan") )
    {
        msg_Err( p_finder, "unsupported XML data format" );
        goto end;
    }

    while( (i_current_node_type = xml_ReaderNextNode( p_xml_reader, &p_node )) > 0 )
    {
        switch( i_current_node_type )
        {
        case XML_READER_STARTELEM:
        {
            if ( ! strcmp( p_node, "addon" ) )
            {
                if ( p_entry ) /* Unclosed tag */
                    addon_entry_Release( p_entry );
                p_entry = addon_entry_New();
                p_entry->psz_source_module = strdup( ADDONS_MODULE_SHORTCUT );
                p_entry->e_flags = ADDON_MANAGEABLE;
                p_entry->e_state = ADDON_NOTINSTALLED;

                while( (attr = xml_ReaderNextAttr( p_xml_reader, &value )) )
                {
                    if ( !strcmp( attr, "type" ) )
                    {
                        p_entry->e_type = ReadType( value );
                    }
                    else if ( !strcmp( attr, "id" ) )
                    {
                        addons_uuid_read( value, & p_entry->uuid );
                    }
                    else if ( !strcmp( attr, "downloads" ) )
                    {
                        p_entry->i_downloads = atoi( value );
                    }
                    else if ( !strcmp( attr, "score" ) )
                    {
                        p_entry->i_score = atol( value );
                    }
                    else if ( !strcmp( attr, "version" ) )
                    {
                        p_entry->psz_version = strdup( value );
                    }
                }

                break;
            }
            if ( !p_entry ) break;

            BINDNODE("name", p_entry->psz_name, TYPE_STRING)
            BINDNODE("archive", p_entry->psz_archive_uri, TYPE_STRING)
            BINDNODE("summary", p_entry->psz_summary, TYPE_STRING)
            BINDNODE("description", p_entry->psz_description, TYPE_STRING)
            BINDNODE("image", p_entry->psz_image_data, TYPE_STRING)
            BINDNODE("creator", p_entry->psz_author, TYPE_STRING)
            BINDNODE("sourceurl", p_entry->psz_source_uri, TYPE_STRING)
            data_pointer.e_type = TYPE_NONE;

            break;
        }
        case XML_READER_TEXT:
            if ( data_pointer.e_type == TYPE_NONE || !p_entry ) break;
            if ( data_pointer.e_type == TYPE_STRING )
                *data_pointer.u_data.ppsz = strdup( p_node );
            else
            if ( data_pointer.e_type == TYPE_LONG )
                *data_pointer.u_data.pl = atol( p_node );
            else
            if ( data_pointer.e_type == TYPE_INTEGER )
                *data_pointer.u_data.pi = atoi( p_node );
            break;

        case XML_READER_ENDELEM:
            if ( !p_entry ) break;
            if ( ! strcmp( p_node, "addon" ) )
            {
                /* then append entry */
                ARRAY_APPEND( p_finder->entries, p_entry );
                p_entry = NULL;
                i_num_entries_created++;
            }

            data_pointer.e_type = TYPE_NONE;
            break;

        default:
            break;
        }
    }

end:
   if ( p_entry ) /* Unclosed tag */
       addon_entry_Release( p_entry );
   xml_ReaderDelete( p_xml_reader );
   return i_num_entries_created;
}
Beispiel #15
0
Datei: qtl.c Projekt: AsamQi/vlc
static int Demux( demux_t *p_demux )
{
    xml_reader_t *p_xml_reader;
    const char *node;
    input_item_t *p_input;
    int i_ret = -1;

    /* List of all possible attributes. The only required one is "src" */
    bool b_autoplay = false;
    bool b_controler = true;
    qtl_fullscreen_t fullscreen = false;
    char *psz_href = NULL;
    bool b_kioskmode = false;
    qtl_loop_t loop = LOOP_FALSE;
    int i_movieid = -1;
    char *psz_moviename = NULL;
    bool b_playeveryframe = false;
    char *psz_qtnext = NULL;
    bool b_quitwhendone = false;
    char *psz_src = NULL;
    char *psz_mimetype = NULL;
    int i_volume = 100;

    input_item_t *p_current_input = GetCurrentItem(p_demux);

    p_xml_reader = xml_ReaderCreate( p_demux, p_demux->s );
    if( !p_xml_reader )
        goto error;

    /* check root node */
    if( xml_ReaderNextNode( p_xml_reader, &node ) != XML_READER_STARTELEM
     || strcmp( node, "embed" ) )
    {
        msg_Err( p_demux, "invalid root node <%s>", node );

        /* second line has <?quicktime tag ... so we try to skip it */
        msg_Dbg( p_demux, "trying to read one more node" );
        if( xml_ReaderNextNode( p_xml_reader, &node ) != XML_READER_STARTELEM
         || strcmp( node, "embed" ) )
        {
            msg_Err( p_demux, "invalid root node <%s>", node );
            goto error;
        }
    }

    const char *attrname, *value;
    while( (attrname = xml_ReaderNextAttr( p_xml_reader, &value )) != NULL )
    {
        if( !strcmp( attrname, "autoplay" ) )
            b_autoplay = !strcmp( value, "true" );
        else if( !strcmp( attrname, "controler" ) )
            b_controler = !strcmp( attrname, "false" );
        else if( !strcmp( attrname, "fullscreen" ) )
        {
            if( !strcmp( value, "double" ) )
                fullscreen = FULLSCREEN_DOUBLE;
            else if( !strcmp( value, "half" ) )
                fullscreen = FULLSCREEN_HALF;
            else if( !strcmp( value, "current" ) )
                fullscreen = FULLSCREEN_CURRENT;
            else if( !strcmp( value, "full" ) )
                fullscreen = FULLSCREEN_FULL;
            else
                fullscreen = FULLSCREEN_NORMAL;
        }
        else if( !strcmp( attrname, "href" ) )
        {
            free( psz_href );
            psz_href = strdup( value );
        }
        else if( !strcmp( attrname, "kioskmode" ) )
            b_kioskmode = !strcmp( value, "true" );
        else if( !strcmp( attrname, "loop" ) )
        {
            if( !strcmp( value, "true" ) )
                loop = LOOP_TRUE;
            else if( !strcmp( value, "palindrome" ) )
                loop = LOOP_PALINDROME;
            else
                loop = LOOP_FALSE;
        }
        else if( !strcmp( attrname, "movieid" ) )
            i_movieid = atoi( value );
        else if( !strcmp( attrname, "moviename" ) )
        {
            free( psz_moviename );
            psz_moviename = strdup( value );
        }
        else if( !strcmp( attrname, "playeveryframe" ) )
            b_playeveryframe = !strcmp( value, "true" );
        else if( !strcmp( attrname, "qtnext" ) )
        {
            free( psz_qtnext );
            psz_qtnext = strdup( value );
        }
        else if( !strcmp( attrname, "quitwhendone" ) )
            b_quitwhendone = !strcmp( value, "true" );
        else if( !strcmp( attrname, "src" ) )
        {
            free( psz_src );
            psz_src = strdup( value );
        }
        else if( !strcmp( attrname, "mimetype" ) )
        {
            free( psz_mimetype );
            psz_mimetype = strdup( value );
        }
        else if( !strcmp( attrname, "volume" ) )
            i_volume = atoi( value );
        else
            msg_Dbg( p_demux, "Attribute %s with value %s isn't valid",
                     attrname, value );
    }

    msg_Dbg( p_demux, "autoplay: %s (unused by VLC)",
             b_autoplay ? "true": "false" );
    msg_Dbg( p_demux, "controler: %s (unused by VLC)",
             b_controler ? "true": "false" );
    msg_Dbg( p_demux, "fullscreen: %s (unused by VLC)",
             ppsz_fullscreen[fullscreen] );
    msg_Dbg( p_demux, "href: %s", psz_href );
    msg_Dbg( p_demux, "kioskmode: %s (unused by VLC)",
             b_kioskmode ? "true":"false" );
    msg_Dbg( p_demux, "loop: %s (unused by VLC)", ppsz_loop[loop] );
    msg_Dbg( p_demux, "movieid: %d (unused by VLC)", i_movieid );
    msg_Dbg( p_demux, "moviename: %s", psz_moviename );
    msg_Dbg( p_demux, "playeverframe: %s (unused by VLC)",
             b_playeveryframe ? "true":"false" );
    msg_Dbg( p_demux, "qtnext: %s", psz_qtnext );
    msg_Dbg( p_demux, "quitwhendone: %s (unused by VLC)",
             b_quitwhendone ? "true":"false" );
    msg_Dbg( p_demux, "src: %s", psz_src );
    msg_Dbg( p_demux, "mimetype: %s", psz_mimetype );
    msg_Dbg( p_demux, "volume: %d (unused by VLC)", i_volume );


    if( !psz_src )
    {
        msg_Err( p_demux, "Mandatory attribute 'src' not found" );
    }
    else
    {
        input_item_node_t *p_subitems = input_item_node_Create( p_current_input );
        p_input = input_item_New( psz_src, psz_moviename );
#define SADD_INFO( type, field ) if( field ) { input_item_AddInfo( \
                    p_input, "QuickTime Media Link", type, "%s", field ) ; }
        SADD_INFO( "href", psz_href );
        SADD_INFO( _("Mime"), psz_mimetype );
        input_item_node_AppendItem( p_subitems, p_input );
        vlc_gc_decref( p_input );
        if( psz_qtnext )
        {
            p_input = input_item_New( psz_qtnext, NULL );
            input_item_node_AppendItem( p_subitems, p_input );
            vlc_gc_decref( p_input );
        }
        input_item_node_PostAndDelete( p_subitems );
    }

    i_ret = 0; /* Needed for correct operation of go back */

error:
    if( p_xml_reader )
        xml_ReaderDelete( p_xml_reader );

    vlc_gc_decref(p_current_input);

    free( psz_href );
    free( psz_moviename );
    free( psz_qtnext );
    free( psz_src );
    free( psz_mimetype );
    return i_ret;
}
Beispiel #16
0
static int parse_Manifest( stream_t *s )
{
    stream_sys_t *p_sys = s->p_sys;
    xml_reader_t *vlc_reader = NULL;
    int type = UNKNOWN_ES;
    const char *name, *value;
    stream_t *st = s->p_source;
    msg_Dbg( s, "Manifest parsing\n" );

    vlc_reader = xml_ReaderCreate( st, st );
    if( !vlc_reader )
    {
        msg_Err( s, "Failed to open source for parsing" );
        return VLC_EGENERIC;
    }

    const char *node;
    uint8_t *WaveFormatEx;
    sms_stream_t *sms = NULL;
    quality_level_t *ql = NULL;
    custom_attrs_t *cp = NULL;
    int64_t start_time = 0, duration = 0;
    int64_t computed_start_time = 0, computed_duration = 0;
    unsigned next_track_id = 1;
    int loop_count = 0;
    bool b_weird = false;
    int ret = VLC_SUCCESS;

#define TIMESCALE 10000000
    while( (type = xml_ReaderNextNode( vlc_reader, &node )) > 0 )
    {
        switch( type )
        {
            case XML_READER_STARTELEM:

                if( !strcmp( node, "SmoothStreamingMedia" ) )
                {
                    while( (name = xml_ReaderNextAttr( vlc_reader, &value )) )
                    {
                        if( !strcmp( name, "Duration" ) )
                            p_sys->vod_duration = strtoull( value, NULL, 10 );
                        else if( !strcmp( name, "TimeScale" ) )
                            p_sys->timescale = strtoul( value, NULL, 10 );
                        else if ( !strcmp( name, "LookAheadFragmentCount" ) )
                            p_sys->download.lookahead_count = strtoul( value, NULL, 10 );
                    }
                    if( !p_sys->timescale )
                        p_sys->timescale = TIMESCALE;
                }
                else if( !strcmp( node, "StreamIndex" ) )
                {
                    sms_Free( sms );
                    sms = sms_New();
                    if( unlikely( !sms ) )
                    {
                        ret = VLC_ENOMEM;
                        goto cleanup;
                    }
                    sms->id = next_track_id;
                    next_track_id++;

                    while( (name = xml_ReaderNextAttr( vlc_reader, &value )) )
                    {
                        if( !strcmp( name, "Type" ) )
                        {
                            if( !strcmp( value, "video" ) )
                                sms->type = VIDEO_ES;
                            else if( !strcmp( value, "audio" ) )
                                sms->type = AUDIO_ES;
                            else if( !strcmp( value, "text" ) )
                                sms->type = SPU_ES;
                        }

                        else if( !strcmp( name, "Name" ) )
                            sms->name = strdup( value );
                        else if( !strcmp( name, "TimeScale" ) )
                            sms->timescale = strtoull( value, NULL, 10 );
                        else if( !strcmp( name, "FourCC" ) )
                            sms->default_FourCC =
                                VLC_FOURCC( value[0], value[1], value[2], value[3] );

                        else if( !strcmp( name, "Chunks" ) )
                        {
                            sms->vod_chunks_nb = strtoul( value, NULL, 10 );
                            if( sms->vod_chunks_nb == 0 ) /* live */
                                sms->vod_chunks_nb = UINT32_MAX;
                        }

                        else if( !strcmp( name, "QualityLevels" ) )
                            sms->qlevel_nb = strtoul( value, NULL, 10 );
                        else if( !strcmp( name, "Url" ) )
                            sms->url_template = strdup(value);
                    }

                    if( !sms->timescale )
                        sms->timescale = TIMESCALE;

                    if( !sms->name )
                    {
                        if( sms->type == VIDEO_ES )
                            sms->name = strdup( "video" );
                        else if( sms->type == AUDIO_ES )
                            sms->name = strdup( "audio" );
                        else if( sms->type == SPU_ES )
                            sms->name = strdup( "text" );
                    }
                }
                else if ( !strcmp( node, "CustomAttributes" ) )
                {
                    if (!sms || !ql || cp)
                        break;
                    cp = (custom_attrs_t *) calloc( 1, sizeof(*cp) );
                    if( unlikely( !cp ) )
                    {
                        ret = VLC_ENOMEM;
                        goto cleanup;
                    }
                }
                else if ( !strcmp( node, "Attribute" ) )
                {
                    if (!sms || !ql || !cp)
                        break;
                    while( (name = xml_ReaderNextAttr( vlc_reader, &value )) )
                    {
                        if( !strcmp( name, "Name" ) && !cp->psz_key )
                            cp->psz_key = strdup( value );
                        else
                        if( !strcmp( name, "Value" ) && !cp->psz_value )
                            cp->psz_value = strdup( value );
                    }
                }
                else if( !strcmp( node, "QualityLevel" ) )
                {
                    if ( !sms )
                        break;

                    ql = ql_New();
                    if( !ql )
                    {
                        ret = VLC_ENOMEM;
                        goto cleanup;
                    }

                    while( (name = xml_ReaderNextAttr( vlc_reader, &value )) )
                    {
                        if( !strcmp( name, "Index" ) )
                            ql->Index = strtol( value, NULL, 10 );
                        else if( !strcmp( name, "Bitrate" ) )
                            ql->Bitrate = strtoul( value, NULL, 10 );
                        else if( !strcmp( name, "PacketSize" ) )
                            ql->nBlockAlign = strtoul( value, NULL, 10 );
                        else if( !strcmp( name, "FourCC" ) )
                            ql->FourCC = VLC_FOURCC( value[0], value[1],
                                                     value[2], value[3] );
                        else if( !strcmp( name, "CodecPrivateData" ) )
                            ql->CodecPrivateData = strdup( value );
                        else if( !strcmp( name, "WaveFormatEx" ) )
                        {
                            WaveFormatEx = decode_string_hex_to_binary( value );
                            uint16_t data_len = ((uint16_t *)WaveFormatEx)[8];
                            ql->CodecPrivateData = strndup( value + 36, data_len * 2 );

                            uint16_t wf_tag = ((uint16_t *)WaveFormatEx)[0];
                            wf_tag_to_fourcc( wf_tag, &ql->FourCC, NULL );

                            ql->Channels = ((uint16_t *)WaveFormatEx)[1];
                            ql->SamplingRate = ((uint32_t *)WaveFormatEx)[1];
                            ql->nBlockAlign = ((uint16_t *)WaveFormatEx)[6];
                            ql->BitsPerSample = ((uint16_t *)WaveFormatEx)[7];
                            free( WaveFormatEx );
                        }
                        else if( !strcmp( name, "MaxWidth" ) || !strcmp( name, "Width" ) )
                            ql->MaxWidth = strtoul( value, NULL, 10 );
                        else if( !strcmp( name, "MaxHeight" ) || !strcmp( name, "Height" ) )
                            ql->MaxHeight = strtoul( value, NULL, 10 );
                        else if( !strcmp( name, "Channels" ) )
                            ql->Channels = strtoul( value, NULL, 10 );
                        else if( !strcmp( name, "SamplingRate" ) )
                            ql->SamplingRate = strtoul( value, NULL, 10 );
                        else if( !strcmp( name, "BitsPerSample" ) )
                            ql->BitsPerSample = strtoul( value, NULL, 10 );
                    }

                    ARRAY_APPEND( sms->qlevels, ql );
                }
                else if ( !strcmp( node, "Content" ) && sms && !sms->url_template )
                {
                    /* empty(@Url) && ./Content == manifest embedded content */
                    sms_Free( sms );
                    sms = NULL;
                }
                else if( !strcmp( node, "c" ) )
                {
                    if ( !sms )
                        break;
                    loop_count++;
                    start_time = duration = -1;
                    while( (name = xml_ReaderNextAttr( vlc_reader, &value )) )
                    {
                        if( !strcmp( name, "t" ) )
                            start_time = strtoll( value, NULL, 10 );
                        if( !strcmp( name, "d" ) )
                            duration = strtoll( value, NULL, 10 );
                    }
                    if( start_time == -1 )
                    {
                        assert( duration != -1 );
                        computed_start_time += computed_duration;
                        computed_duration = duration;
                    }
                    else if( duration == -1 )
                    {
                        assert( start_time != -1 );
                        /* Handle weird Manifests which give only the start time
                         * of the first segment. In those cases, we have to look
                         * at the start time of the second segment to compute
                         * the duration of the first one. */
                        if( loop_count == 1 )
                        {
                            b_weird = true;
                            computed_start_time = start_time;
                            continue;
                        }

                        computed_duration = start_time - computed_start_time;
                        if( !b_weird )
                            computed_start_time = start_time;
                    }
                    else
                    {
                        if( b_weird )
                            computed_duration = start_time - computed_start_time;
                        else
                        {
                            computed_start_time = start_time;
                            computed_duration = duration;
                        }
                    }

                    if( unlikely( chunk_AppendNew( sms, computed_duration,
                                        computed_start_time ) == NULL ) )
                    {
                        ret = VLC_ENOMEM;
                        goto cleanup;
                    }
                    if( b_weird && start_time != -1 )
                        computed_start_time = start_time;
                }
                break;

            case XML_READER_ENDELEM:
                if ( !strcmp( node, "CustomAttributes" ) )
                {
                    if ( cp )
                    {
                        ARRAY_APPEND(ql->custom_attrs, cp);
                        cp = NULL;
                    }
                }
                else if ( !strcmp( node, "Attribute" ) )
                {
                    if( !cp->psz_key || !cp->psz_value )
                    {
                        cleanup_attributes( &cp );
                    }
                }
                else if( strcmp( node, "StreamIndex" ) )
                    break;
                else if ( sms )
                {
                    ARRAY_APPEND( p_sys->sms, sms );

                    computed_start_time = 0;
                    computed_duration = 0;
                    loop_count = 0;
                    if( b_weird && !chunk_AppendNew( sms, computed_duration, computed_start_time ) )
                    {
                        ret = VLC_ENOMEM;
                        goto cleanup;
                    }

                    b_weird = false;

                    if( sms->qlevel_nb == 0 )
                        sms->qlevel_nb = sms->qlevels.i_size;

                    sms = NULL;
                }
                break;

            case XML_READER_TEXT:
                break;
            default:
                ret = VLC_EGENERIC;
                goto cleanup;
        }
    }
#undef TIMESCALE

cleanup:
    cleanup_attributes( &cp );
    sms_Free( sms );
    xml_ReaderDelete( vlc_reader );

    return ret;
}
Beispiel #17
0
/* <genrelist>
 *   <genre name="the name"></genre>
 *   ...
 * </genrelist>
 **/
static int DemuxGenre( demux_t *p_demux )
{
    demux_sys_t *p_sys = p_demux->p_sys;
    char *psz_name = NULL; /* genre name */
    char *psz_eltname = NULL; /* tag name */
    input_item_t *p_input;

    while( xml_ReaderRead( p_sys->p_xml_reader ) == 1 )
    {
        int i_type;

        // Get the node type
        i_type = xml_ReaderNodeType( p_sys->p_xml_reader );
        switch( i_type )
        {
            // Error
            case -1:
                return -1;
                break;

            case XML_READER_STARTELEM:
                // Read the element name
                psz_eltname = xml_ReaderName( p_sys->p_xml_reader );
                if( !psz_eltname ) return -1;

                if( !strcmp( psz_eltname, "genre" ) )
                {
                    // Read the attributes
                    while( xml_ReaderNextAttr( p_sys->p_xml_reader ) == VLC_SUCCESS )
                    {
                        char *psz_attrname = xml_ReaderName( p_sys->p_xml_reader );
                        char *psz_attrvalue =
                            xml_ReaderValue( p_sys->p_xml_reader );
                        if( !psz_attrname || !psz_attrvalue )
                        {
                            FREENULL(psz_attrname);
                            FREENULL(psz_attrvalue);
                            free(psz_eltname);
                            /*FIXME: isn't return a bit too much. what about break*/
                            return -1;
                        }

                        GET_VALUE( name )
                        else
                        {
                            msg_Warn( p_demux,
                                      "unexpected attribure %s in element %s",
                                      psz_attrname,psz_eltname );
                        }
                        free( psz_attrname );
                        free( psz_attrvalue );
                    }
                }
                free( psz_eltname ); psz_eltname = NULL;
                break;

            case XML_READER_TEXT:
                break;

            // End element
            case XML_READER_ENDELEM:
                // Read the element name
                psz_eltname = xml_ReaderName( p_sys->p_xml_reader );
                if( !psz_eltname ) return -1;
                if( !strcmp( psz_eltname, "genre" ) )
                {
                    char* psz_mrl;
                    if( asprintf( &psz_mrl, SHOUTCAST_BASE_URL "?genre=%s",
                             psz_name ) != -1 )
                    {
                        p_input = input_item_New( p_demux, psz_mrl, psz_name );
                        input_item_CopyOptions( p_sys->p_current_input, p_input );
                        free( psz_mrl );
                        input_item_AddSubItem( p_sys->p_current_input, p_input );
                        vlc_gc_decref( p_input );
                    }
                    FREENULL( psz_name );
                }
                FREENULL( psz_eltname );
                break;
        }
    }
    return 0;
}
Beispiel #18
0
static int Demux( demux_t *p_demux )
{
    int i_ret = -1;

    xml_reader_t *p_xml_reader = NULL;
    char *psz_elname = NULL;
    const char *node;
    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);

    free( stream_ReadLine( p_demux->s ) );

    p_xml_reader = xml_ReaderCreate( p_demux, p_demux->s );
    if( !p_xml_reader )
        return -1;

    /* xml */
    /* check root node */
    if( xml_ReaderNextNode( p_xml_reader, &node ) != XML_READER_STARTELEM )
    {
        msg_Err( p_demux, "invalid file (no root node)" );
        goto end;
    }

    if( strcmp( node, "WinampXML" ) )
    {
        msg_Err( p_demux, "invalid root node: %s", node );
        goto end;
    }

    /* root node should not have any attributes, and should only
     * contain the "playlist node */

    /* Skip until 1st child node */
    while( (i_ret = xml_ReaderNextNode( p_xml_reader, &node )) != XML_READER_STARTELEM )
        if( i_ret <= 0 )
        {
            msg_Err( p_demux, "invalid file (no child node)" );
            goto end;
        }

    if( strcmp( node, "playlist" ) )
    {
        msg_Err( p_demux, "invalid child node %s", node );
        goto end;
    }

    // Read the attributes
    const char *attr, *value;
    while( (attr = xml_ReaderNextAttr( p_xml_reader, &value )) != NULL )
    {
        if( !strcmp( attr, "num_entries" ) )
            msg_Dbg( p_demux, "playlist has %d entries", atoi(value) );
        else if( !strcmp( attr, "label" ) )
            input_item_SetName( p_current_input, value );
        else
            msg_Warn( p_demux, "stray attribute %s with value %s in element"
                      " <playlist>", attr, value );
    }

    p_subitems = input_item_node_Create( p_current_input );

    while( (i_ret = xml_ReaderNextNode( p_xml_reader, &node )) > 0 )
    {
        // Get the node type
        switch( i_ret )
        {
            case XML_READER_STARTELEM:
            {
                // Read the element name
                free( psz_elname );
                psz_elname = strdup( node );
                if( unlikely(!psz_elname) )
                    goto end;

                // Read the attributes
                while( (attr = xml_ReaderNextAttr( p_xml_reader, &value )) )
                {
                    if( !strcmp( psz_elname, "entry" ) &&
                        !strcmp( attr, "Playstring" ) )
                    {
                        free( psz_mrl );
                        psz_mrl = strdup( value );
                    }
                    else
                    {
                        msg_Warn( p_demux, "unexpected attribute %s in <%s>",
                                  attr, psz_elname );
                    }
                }
                break;
            }

            case XML_READER_TEXT:
            {
                char **p;

                if( psz_elname == NULL )
                    break;
                if( IsWhitespace( node ) )
                    break;
                if( !strcmp( psz_elname, "Name" ) )
                    p = &psz_title;
                else if( !strcmp( psz_elname, "Genre" ) )
                    p = &psz_genre;
                else if( !strcmp( psz_elname, "Nowplaying" ) )
                    p = &psz_now;
                else if( !strcmp( psz_elname, "Listeners" ) )
                    p = &psz_listeners;
                else if( !strcmp( psz_elname, "Bitrate" ) )
                    p = &psz_bitrate;
                else
                {
                    msg_Warn( p_demux, "unexpected text in element <%s>",
                              psz_elname );
                    break;
                }
                free( *p );
                *p = strdup( node );
                break;
            }

            // End element
            case XML_READER_ENDELEM:
            {
                // Read the element name
                if( !strcmp( node, "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 );
                }
                FREENULL( psz_elname );
                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_reader );
    return i_ret;
}
Beispiel #19
0
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 ) )
Beispiel #20
0
static int Demux( demux_t *p_demux )
{
    const char *psz_node = NULL;
    char *psz_txt = NULL;
    char *psz_base = FindPrefix( p_demux );
    char *psz_title_asx = NULL;
    char *psz_entryref = NULL;

    xml_reader_t *p_xml_reader = NULL;
    input_item_t *p_current_input = GetCurrentItem( p_demux );
    input_item_node_t *p_subitems = NULL;

    bool b_first_node = false;
    int i_type;
    int i_n_entry = 0;

    p_xml_reader = xml_ReaderCreate( p_demux, p_demux->s );
    if( !p_xml_reader )
    {
        msg_Err( p_demux, "Cannot parse ASX input file as XML");
        goto error;
    }

    p_subitems = input_item_node_Create( p_current_input );

    do
    {
        i_type = xml_ReaderNextNode( p_xml_reader, &psz_node );
        if( i_type == XML_READER_STARTELEM )
        {
            if( !b_first_node )
            {
                if(!strncasecmp( psz_node, "ASX", 3 ) )
                    b_first_node = true;
                else
                {
                    msg_Err( p_demux, "invalid root node" );
                    goto error;
                }
            }

            /* Metadata Node Handler */
            if( !strncasecmp( psz_node, "TITLE", 5 ) )
            {
                ReadElement( p_xml_reader, &psz_title_asx );
                input_item_SetTitle( p_current_input, psz_title_asx );
            }
            else if( !strncasecmp( psz_node, "AUTHOR", 6 ) )
            {
                ReadElement( p_xml_reader, &psz_txt );
                input_item_SetArtist( p_current_input, psz_txt );
            }
            else if( !strncasecmp( psz_node, "COPYRIGHT", 9 ) )
            {
                ReadElement( p_xml_reader, &psz_txt );
                input_item_SetCopyright( p_current_input, psz_txt );
            }
            else if( !strncasecmp( psz_node, "MOREINFO", 8 ) )
            {
                const char *psz_tmp;
                do
                {
                    psz_tmp = xml_ReaderNextAttr( p_xml_reader, &psz_node );
                }
                while( psz_tmp && strncasecmp( psz_tmp, "HREF", 4 ) );

                if( !psz_tmp )  // If HREF attribute doesn't exist
                    ReadElement( p_xml_reader, &psz_txt );
                else
                    psz_txt = strdup( psz_node );

                resolve_xml_special_chars( psz_txt );
                input_item_SetURL( p_current_input, psz_txt );
            }
            else if( !strncasecmp( psz_node, "ABSTRACT", 8 ) )
            {
                ReadElement( p_xml_reader, &psz_txt );
                input_item_SetDescription( p_current_input, psz_txt );
            }
            else
            /* Base Node handler */
            if( !strncasecmp( psz_node, "BASE", 4 ) )
                ReadElement( p_xml_reader, &psz_base );
            else
            /* Entry Ref Handler */
            if( !strncasecmp( psz_node, "ENTRYREF", 7 ) )
            {
                const char *psz_tmp;
                do
                {
                    psz_tmp = xml_ReaderNextAttr( p_xml_reader, &psz_node );
                }
                while( psz_tmp && !strncasecmp( psz_tmp, "HREF", 4 ) );

                /* Create new input item */
                input_item_t *p_input;
                psz_txt = strdup( psz_node );
                resolve_xml_special_chars( psz_txt );
                p_input = input_item_New( psz_txt, psz_title_asx );
                input_item_CopyOptions( p_current_input, p_input );
                input_item_node_AppendItem( p_subitems, p_input );

                vlc_gc_decref( p_input );
            }
            else
            /* Entry Handler */
            if( !strncasecmp( psz_node, "ENTRY", 5 ) )
            {
                ProcessEntry( &i_n_entry, p_xml_reader, p_subitems,
                              p_current_input, psz_base);
            }
        /* FIXME Unsupported elements
            PARAM
            EVENT
            REPEAT
            ENDMARK
            STARTMARK
        */
        }
    }
    while( i_type != XML_READER_ENDELEM || strncasecmp( psz_node, "ASX", 3 ) );

    input_item_node_PostAndDelete( p_subitems );
    p_subitems = NULL;


error:
    free( psz_base );
    free( psz_title_asx );
    free( psz_entryref );
    free( psz_txt );

    if( p_xml_reader)
        xml_ReaderDelete( p_xml_reader );
    if( p_subitems )
        input_item_node_Delete( p_subitems );

    vlc_gc_decref( p_current_input );

    return 0;
}
/* radio stations:
 * <stationlist>
 *   <tunein base="/sbin/tunein-station.pls"></tunein>
 *   <station name="the name"
 *            mt="mime type"
 *            id="the id"
 *            br="bit rate"
 *            genre="A big genre string"
 *            ct="current track name/author/..."
 *            lc="listener count"></station>
 * </stationlist>
 *
 * TV stations:
 * <stationlist>
 *   <tunein base="/sbin/tunein-station.pls"></tunein>
 *   <station name="the name"
 *            id="the id"
 *            br="bit rate"
 *            rt="rating"
 *            load="server load ?"
 *            ct="current track name/author/..."
 *            genre="A big genre string"
 *            lc="listener count"></station>
 * </stationlist>
 **/
static int DemuxStation( demux_t *p_demux, xml_reader_t *p_xml_reader,
                         input_item_node_t *p_input_node, bool b_adult )
{
    char *psz_base = NULL; /* */

    char *psz_name = NULL; /* genre name */
    char *psz_mt = NULL; /* mime type */
    char *psz_id = NULL; /* id */
    char *psz_br = NULL; /* bit rate */
    char *psz_genre = NULL; /* genre */
    char *psz_ct = NULL; /* current track */
    char *psz_lc = NULL; /* listener count */

    /* If these are set then it's *not* a radio but a TV */
    char *psz_rt = NULL; /* rating for shoutcast TV */
    char *psz_load = NULL; /* load for shoutcast TV */

    const char *node; /* tag name */
    int i_type;

    while( (i_type = xml_ReaderNextNode( p_xml_reader, &node )) > 0 )
    {
        switch( i_type )
        {
            case XML_READER_STARTELEM:
                // Read the attributes
                if( !strcmp( node, "tunein" ) )
                {
                    const char *name, *value;
                    while( (name = xml_ReaderNextAttr( p_xml_reader, &value )) )
                    {
                        if( !strcmp( name, "base" ) )
                        {
                            free( psz_base );
                            psz_base = strdup( value );
                        }
                        else
                            msg_Warn( p_demux,
                                      "unexpected attribute %s in <%s>",
                                      name, node );
                    }
                }
                else if( !strcmp( node, "station" ) )
                {
                    const char *name, *value;
                    while( (name = xml_ReaderNextAttr( p_xml_reader, &value )) )
                    {
                        char **p = NULL;
                        if( !strcmp( name, "name" ) )
                            p = &psz_name;
                        else if ( !strcmp( name, "mt" ) )
                            p = &psz_mt;
                        else if ( !strcmp( name, "id" ) )
                            p = &psz_id;
                        else if ( !strcmp( name, "br" ) )
                            p = &psz_br;
                        else if ( !strcmp( name, "genre" ) )
                            p = &psz_genre;
                        else if ( !strcmp( name, "ct" ) )
                            p = &psz_ct;
                        else if ( !strcmp( name, "lc" ) )
                            p = &psz_lc;
                        else if ( !strcmp( name, "rt" ) )
                            p = &psz_rt;
                        else if ( !strcmp( name, "load" ) )
                            p = &psz_load;
                        if( p != NULL )
                        {
                            free( *p );
                            *p = strdup( value );
                        }
                        else
                            msg_Warn( p_demux,
                                      "unexpected attribute %s in <%s>",
                                      name, node );
                    }
                }
                break;

            // End element
            case XML_READER_ENDELEM:
                if( !strcmp( node, "station" ) &&
                    ( psz_base || ( psz_rt && psz_load &&
                    ( b_adult || strcmp( psz_rt, "NC17" ) ) ) ) )
                {
                    char *psz_mrl = NULL;
                    if( psz_rt || psz_load )
                    {
                        /* tv */
                        if( asprintf( &psz_mrl, SHOUTCAST_TV_TUNEIN_URL "%s",
                                 psz_id ) == -1)
                            psz_mrl = NULL;
                    }
                    else
                    {
                        /* radio */
                        if( asprintf( &psz_mrl, SHOUTCAST_TUNEIN_BASE_URL "%s?id=%s",
                             psz_base, psz_id ) == -1 )
                            psz_mrl = NULL;
                    }

                    /* Create the item */
                    input_item_t *p_input;
                    p_input = input_item_New( psz_mrl, psz_name );
                    input_item_CopyOptions( p_input_node->p_item, p_input );
                    free( psz_mrl );

#define SADD_INFO( type, field ) \
                    if( field ) \
                        input_item_AddInfo( p_input, _("Shoutcast"), \
                                            vlc_gettext(type), "%s", field )
                    SADD_INFO( N_("Mime"), psz_mt );
                    SADD_INFO( N_("Bitrate"), psz_br );
                    SADD_INFO( N_("Listeners"), psz_lc );
                    SADD_INFO( N_("Load"), psz_load );
                    if( psz_genre )
                        input_item_SetGenre( p_input, psz_genre );
                    if( psz_ct )
                        input_item_SetNowPlaying( p_input, psz_ct );
                    if( psz_rt )
                        input_item_SetRating( p_input, psz_rt );
                    input_item_node_AppendItem( p_input_node, p_input );
                    vlc_gc_decref( p_input );
                    FREENULL( psz_base );
                    FREENULL( psz_name );
                    FREENULL( psz_mt );
                    FREENULL( psz_id );
                    FREENULL( psz_br );
                    FREENULL( psz_genre );
                    FREENULL( psz_ct );
                    FREENULL( psz_lc );
                    FREENULL( psz_rt );
                    FREENULL( psz_load );
                }
                break;
        }
    }
    /* FIXME: leaks on missing ENDELEMENT? */
    return 0;
}
Beispiel #22
0
static void ParseUSFHeaderTags( decoder_t *p_dec, xml_reader_t *p_xml_reader )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    const char *node;
    ssa_style_t *p_ssa_style = NULL;
    int i_style_level = 0;
    int i_metadata_level = 0;
    int type;

    while( (type = xml_ReaderNextNode( p_xml_reader, &node )) > 0 )
    {
        switch( type )
        {
            case XML_READER_ENDELEM:
                switch (i_style_level)
                {
                    case 0:
                        if( !strcasecmp( "metadata", node ) && (i_metadata_level == 1) )
                            i_metadata_level--;
                        break;
                    case 1:
                        if( !strcasecmp( "styles", node ) )
                            i_style_level--;
                        break;
                    case 2:
                        if( !strcasecmp( "style", node ) )
                        {
                            TAB_APPEND( p_sys->i_ssa_styles, p_sys->pp_ssa_styles, p_ssa_style );

                            p_ssa_style = NULL;
                            i_style_level--;
                        }
                        break;
                }
                break;

            case XML_READER_STARTELEM:
                if( !strcasecmp( "metadata", node ) && (i_style_level == 0) )
                    i_metadata_level++;
                else if( !strcasecmp( "resolution", node ) &&
                         ( i_metadata_level == 1) )
                {
                    const char *attr, *val;
                    while( (attr = xml_ReaderNextAttr( p_xml_reader, &val )) )
                    {
                        if( !strcasecmp( "x", attr ) )
                            p_sys->i_original_width = atoi( val );
                        else if( !strcasecmp( "y", attr ) )
                            p_sys->i_original_height = atoi( val );
                    }
                }
                else if( !strcasecmp( "styles", node ) && (i_style_level == 0) )
                {
                    i_style_level++;
                }
                else if( !strcasecmp( "style", node ) && (i_style_level == 1) )
                {
                    i_style_level++;

                    p_ssa_style = calloc( 1, sizeof(ssa_style_t) );
                    if( unlikely(!p_ssa_style) )
                        return;
                    p_ssa_style->p_style = text_style_Create( STYLE_NO_DEFAULTS );
                    if( unlikely(!p_ssa_style->p_style) )
                    {
                        free(p_ssa_style);
                        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
                     */
                    for( int 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->p_style, p_default_style->p_style );
                            p_ssa_style->psz_stylename = NULL;
                        }
                    }

                    const char *attr, *val;
                    while( (attr = xml_ReaderNextAttr( p_xml_reader, &val )) )
                    {
                        if( !strcasecmp( "name", attr ) )
                        {
                            free( p_ssa_style->psz_stylename );
                            p_ssa_style->psz_stylename = strdup( val );
                        }
                    }
                }
                else if( !strcasecmp( "fontstyle", node ) && (i_style_level == 2) )
                {
                    const char *attr, *val;
                    while( (attr = xml_ReaderNextAttr( p_xml_reader, &val )) )
                    {
                        if( !strcasecmp( "face", attr ) )
                        {
                            free( p_ssa_style->p_style->psz_fontname );
                            p_ssa_style->p_style->psz_fontname = strdup( val );
                        }
                        else if( !strcasecmp( "size", attr ) )
                        {
                            if( ( *val == '+' ) || ( *val == '-' ) )
                            {
                                int i_value = atoi( val );

                                if( ( i_value >= -5 ) && ( i_value <= 5 ) )
                                    p_ssa_style->p_style->i_font_size  +=
                                       ( i_value * p_ssa_style->p_style->i_font_size ) / 10;
                                else if( i_value < -5 )
                                    p_ssa_style->p_style->i_font_size  = - i_value;
                                else if( i_value > 5 )
                                    p_ssa_style->p_style->i_font_size  = i_value;
                            }
                            else
                                p_ssa_style->p_style->i_font_size  = atoi( val );
                        }
                        else if( !strcasecmp( "italic", attr ) )
                        {
                            if( !strcasecmp( "yes", val ))
                                p_ssa_style->p_style->i_style_flags |= STYLE_ITALIC;
                            else
                                p_ssa_style->p_style->i_style_flags &= ~STYLE_ITALIC;
                            p_ssa_style->p_style->i_features |= STYLE_HAS_FLAGS;
                        }
                        else if( !strcasecmp( "weight", attr ) )
                        {
                            if( !strcasecmp( "bold", val ))
                                p_ssa_style->p_style->i_style_flags |= STYLE_BOLD;
                            else
                                p_ssa_style->p_style->i_style_flags &= ~STYLE_BOLD;
                            p_ssa_style->p_style->i_features |= STYLE_HAS_FLAGS;
                        }
                        else if( !strcasecmp( "underline", attr ) )
                        {
                            if( !strcasecmp( "yes", val ))
                                p_ssa_style->p_style->i_style_flags |= STYLE_UNDERLINE;
                            else
                                p_ssa_style->p_style->i_style_flags &= ~STYLE_UNDERLINE;
                            p_ssa_style->p_style->i_features |= STYLE_HAS_FLAGS;
                        }
                        else if( !strcasecmp( "color", attr ) )
                        {
                            if( *val == '#' )
                            {
                                unsigned long col = strtol(val+1, NULL, 16);
                                 p_ssa_style->p_style->i_font_color = (col & 0x00ffffff);
                                 p_ssa_style->p_style->i_font_alpha = (col >> 24) & 0xff;
                                 p_ssa_style->p_style->i_features |= STYLE_HAS_FONT_COLOR
                                                                   | STYLE_HAS_FONT_ALPHA;
                            }
                        }
                        else if( !strcasecmp( "outline-color", attr ) )
                        {
                            if( *val == '#' )
                            {
                                unsigned long col = strtol(val+1, NULL, 16);
                                p_ssa_style->p_style->i_outline_color = (col & 0x00ffffff);
                                p_ssa_style->p_style->i_outline_alpha = (col >> 24) & 0xff;
                                p_ssa_style->p_style->i_features |= STYLE_HAS_OUTLINE_COLOR
                                                                  | STYLE_HAS_OUTLINE_ALPHA;
                            }
                        }
                        else if( !strcasecmp( "outline-level", attr ) )
                        {
                            p_ssa_style->p_style->i_outline_width = atoi( val );
                        }
                        else if( !strcasecmp( "shadow-color", attr ) )
                        {
                            if( *val == '#' )
                            {
                                unsigned long col = strtol(val+1, NULL, 16);
                                p_ssa_style->p_style->i_shadow_color = (col & 0x00ffffff);
                                p_ssa_style->p_style->i_shadow_alpha = (col >> 24) & 0xff;
                                p_ssa_style->p_style->i_features |= STYLE_HAS_SHADOW_COLOR
                                                                  | STYLE_HAS_SHADOW_ALPHA;
                            }
                        }
Beispiel #23
0
static int Demux( demux_t *p_demux )
{
    int i_ret = -1;

    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);

    psz_elname = stream_ReadLine( p_demux->s );
    free( psz_elname );
    psz_elname = NULL;

    p_xml_reader = xml_ReaderCreate( p_demux, 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_reader );
    return i_ret;
}
Beispiel #24
0
/* radio stations:
 * <stationlist>
 *   <tunein base="/sbin/tunein-station.pls"></tunein>
 *   <station name="the name"
 *            mt="mime type"
 *            id="the id"
 *            br="bit rate"
 *            genre="A big genre string"
 *            ct="current track name/author/..."
 *            lc="listener count"></station>
 * </stationlist>
 *
 * TV stations:
 * <stationlist>
 *   <tunein base="/sbin/tunein-station.pls"></tunein>
 *   <station name="the name"
 *            id="the id"
 *            br="bit rate"
 *            rt="rating"
 *            load="server load ?"
 *            ct="current track name/author/..."
 *            genre="A big genre string"
 *            lc="listener count"></station>
 * </stationlist>
 **/
static int DemuxStation( demux_t *p_demux )
{
    demux_sys_t *p_sys = p_demux->p_sys;
    input_item_t *p_input;

    char *psz_base = NULL; /* */

    char *psz_name = NULL; /* genre name */
    char *psz_mt = NULL; /* mime type */
    char *psz_id = NULL; /* id */
    char *psz_br = NULL; /* bit rate */
    char *psz_genre = NULL; /* genre */
    char *psz_ct = NULL; /* current track */
    char *psz_lc = NULL; /* listener count */

    /* If these are set then it's *not* a radio but a TV */
    char *psz_rt = NULL; /* rating for shoutcast TV */
    char *psz_load = NULL; /* load for shoutcast TV */

    char *psz_eltname = NULL; /* tag name */

    while( xml_ReaderRead( p_sys->p_xml_reader ) == 1 )
    {
        int i_type;

        // Get the node type
        i_type = xml_ReaderNodeType( p_sys->p_xml_reader );
        switch( i_type )
        {
            // Error
            case -1:
                return -1;
                break;

            case XML_READER_STARTELEM:
                // Read the element name
                psz_eltname = xml_ReaderName( p_sys->p_xml_reader );
                if( !psz_eltname ) return -1;

                // Read the attributes
                if( !strcmp( psz_eltname, "tunein" ) )
                {
                    while( xml_ReaderNextAttr( p_sys->p_xml_reader ) == VLC_SUCCESS )
                    {
                        char *psz_attrname = xml_ReaderName( p_sys->p_xml_reader );
                        char *psz_attrvalue =
                            xml_ReaderValue( p_sys->p_xml_reader );
                        if( !psz_attrname || !psz_attrvalue )
                        {
                            free( psz_eltname );
                            free( psz_attrname );
                            free( psz_attrvalue );
                            return -1;
                        }

                        GET_VALUE( base )
                        else
                        {
                            msg_Warn( p_demux,
                                      "unexpected attribure %s in element %s",
                                      psz_attrname, psz_eltname );
                        }
                        free( psz_attrname );
                        free( psz_attrvalue );
                    }
                }
                else if( !strcmp( psz_eltname, "station" ) )
                {
                    while( xml_ReaderNextAttr( p_sys->p_xml_reader ) == VLC_SUCCESS )
                    {
                        char *psz_attrname = xml_ReaderName( p_sys->p_xml_reader );
                        char *psz_attrvalue =
                            xml_ReaderValue( p_sys->p_xml_reader );
                        if( !psz_attrname || !psz_attrvalue )
                        {
                            free( psz_eltname );
                            free( psz_attrname );
                            free( psz_attrvalue );
                            return -1;
                        }

                        GET_VALUE( name )
                        else GET_VALUE( mt )
                        else GET_VALUE( id )
                        else GET_VALUE( br )
                        else GET_VALUE( genre )
                        else GET_VALUE( ct )
                        else GET_VALUE( lc )
                        else GET_VALUE( rt )
                        else GET_VALUE( load )
                        else
                        {
                            msg_Warn( p_demux,
                                      "unexpected attribute %s in element %s",
                                      psz_attrname, psz_eltname );
                        }
                        free( psz_attrname );
                        free( psz_attrvalue );
                    }
                }
                free( psz_eltname );
                break;

            case XML_READER_TEXT:
                break;

            // End element
            case XML_READER_ENDELEM:
                // Read the element name
                psz_eltname = xml_ReaderName( p_sys->p_xml_reader );
                if( !psz_eltname ) return -1;
                if( !strcmp( psz_eltname, "station" ) &&
                    ( psz_base || ( psz_rt && psz_load &&
                    ( p_sys->b_adult || strcmp( psz_rt, "NC17" ) ) ) ) )
                {
                    char *psz_mrl = NULL;
                    if( psz_rt || psz_load )
                    {
                        /* tv */
                        if( asprintf( &psz_mrl, SHOUTCAST_TV_TUNEIN_URL "%s",
                                 psz_id ) == -1)
                            psz_mrl = NULL;
                    }
                    else
                    {
                        /* radio */
                        if( asprintf( &psz_mrl, SHOUTCAST_TUNEIN_BASE_URL "%s?id=%s",
                             psz_base, psz_id ) == -1 )
                            psz_mrl = NULL;
                    }
                    p_input = input_item_New( p_demux, psz_mrl, psz_name );
                    input_item_CopyOptions( p_sys->p_current_input, p_input );
                    free( psz_mrl );

#define SADD_INFO( type, field ) \
                    if( field ) \
                        input_item_AddInfo( p_input, _("Shoutcast"), \
                                            vlc_gettext(type), "%s", field )
                    SADD_INFO( N_("Mime"), psz_mt );
                    SADD_INFO( N_("Bitrate"), psz_br );
                    SADD_INFO( N_("Listeners"), psz_lc );
                    SADD_INFO( N_("Load"), psz_load );
                    if( psz_genre )
                        input_item_SetGenre( p_input, psz_genre );
                    if( psz_ct )
                        input_item_SetNowPlaying( p_input, psz_ct );
                    if( psz_rt )
                        input_item_SetRating( p_input, psz_rt );
                    input_item_AddSubItem( p_sys->p_current_input, p_input );
                    vlc_gc_decref( p_input );
                    FREENULL( psz_name );
                    FREENULL( psz_mt );
                    FREENULL( psz_id );
                    FREENULL( psz_br );
                    FREENULL( psz_genre );
                    FREENULL( psz_ct );
                    FREENULL( psz_lc );
                    FREENULL( psz_rt );
                }
                free( psz_eltname );
                break;
        }
    }
Beispiel #25
0
/****************************************************************************
 * 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);
    const char *node;
    char *psz_eltname = NULL;

    bool b_is_item = false;
    bool b_is_image = false;

    int i_item = 0;
    int type;

    while( (type = xml_ReaderNextNode( p_xml_reader, &node )) > 0 )
    {
        switch( type )
        {
        case XML_READER_STARTELEM:
#ifdef RSS_DEBUG
            msg_Dbg( p_filter, "element <%s>", node );
#endif
            psz_eltname = strdup( node );
            if( unlikely(!psz_eltname) )
                goto end;

            /* rss or atom */
            if( !strcmp( node, "item" ) || !strcmp( node, "entry" ) )
            {
                b_is_item = true;
                p_feed->i_items++;
                p_feed->p_items = (rss_item_t *)xrealloc( p_feed->p_items,
                                     p_feed->i_items * sizeof( rss_item_t ) );			// sunqueen modify
                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( node, "image" ) )
            {
                b_is_image = true;
            }
            /* atom */
            else if( !strcmp( node, "link" ) )
            {
                const char *name, *value;
                char *psz_href = NULL;
                char *psz_rel = NULL;

                while( (name = xml_ReaderNextAttr( p_xml_reader, &value )) != NULL )
                {
                    if( !strcmp( name, "rel" ) )
                    {
                        free( psz_rel );
                        psz_rel = strdup( value );
                    }
                    else if( !strcmp( name, "href" ) )
                    {
                        free( psz_href );
                        psz_href = strdup( value );
                    }
                }

                /* "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:
            FREENULL( psz_eltname );
#ifdef RSS_DEBUG
            msg_Dbg( p_filter, "element end </%s>", node );
#endif
            /* rss or atom */
            if( !strcmp( node, "item" ) || !strcmp( node, "entry" ) )
            {
                b_is_item = false;
                i_item++;
            }
            /* rss */
            else if( !strcmp( node, "image" ) )
            {
                b_is_image = false;
            }
            break;

        case XML_READER_TEXT:
        {
            if( !psz_eltname )
                break;

            char *psz_eltvalue = removeWhiteChars( node );

#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;
}
Beispiel #26
0
Datei: qtl.c Projekt: IAPark/vlc
static int ReadDir( stream_t *p_demux, input_item_node_t *p_subitems )
{
    xml_reader_t *p_xml_reader;
    input_item_t *p_input;
    int i_ret = -1;

    /* List of all possible attributes. The only required one is "src" */
    bool b_autoplay = false;
    bool b_controller = true;
    qtl_fullscreen_t fullscreen = false;
    char *psz_href = NULL;
    bool b_kioskmode = false;
    qtl_loop_t loop = LOOP_FALSE;
    int i_movieid = -1;
    char *psz_moviename = NULL;
    bool b_playeveryframe = false;
    char *psz_qtnext = NULL;
    bool b_quitwhendone = false;
    char *psz_src = NULL;
    char *psz_mimetype = NULL;
    int i_volume = 100;

    p_xml_reader = xml_ReaderCreate( p_demux, p_demux->p_source );
    if( !p_xml_reader )
        goto error;

    for( int i = 0;; ++i ) /* locate root node */
    {
        const char *node;
        if( i == ROOT_NODE_MAX_DEPTH ||
            xml_ReaderNextNode( p_xml_reader, &node ) != XML_READER_STARTELEM )
        {
            msg_Err( p_demux, "unable to locate root-node" );
            goto error;
        }

        if( strcmp( node, "embed" ) == 0 )
            break; /* found it */

        msg_Dbg( p_demux, "invalid root node <%s>, trying next (%d / %d)",
                           node, i + 1, ROOT_NODE_MAX_DEPTH );
    }

    const char *attrname, *value;
    while( (attrname = xml_ReaderNextAttr( p_xml_reader, &value )) != NULL )
    {
        if( !strcmp( attrname, "autoplay" ) )
            b_autoplay = !strcmp( value, "true" );
        else if( !strcmp( attrname, "controller" ) )
            b_controller = !strcmp( attrname, "false" );
        else if( !strcmp( attrname, "fullscreen" ) )
        {
            if( !strcmp( value, "double" ) )
                fullscreen = FULLSCREEN_DOUBLE;
            else if( !strcmp( value, "half" ) )
                fullscreen = FULLSCREEN_HALF;
            else if( !strcmp( value, "current" ) )
                fullscreen = FULLSCREEN_CURRENT;
            else if( !strcmp( value, "full" ) )
                fullscreen = FULLSCREEN_FULL;
            else
                fullscreen = FULLSCREEN_NORMAL;
        }
        else if( !strcmp( attrname, "href" ) )
        {
            free( psz_href );
            psz_href = strdup( value );
        }
        else if( !strcmp( attrname, "kioskmode" ) )
            b_kioskmode = !strcmp( value, "true" );
        else if( !strcmp( attrname, "loop" ) )
        {
            if( !strcmp( value, "true" ) )
                loop = LOOP_TRUE;
            else if( !strcmp( value, "palindrome" ) )
                loop = LOOP_PALINDROME;
            else
                loop = LOOP_FALSE;
        }
        else if( !strcmp( attrname, "movieid" ) )
            i_movieid = atoi( value );
        else if( !strcmp( attrname, "moviename" ) )
        {
            free( psz_moviename );
            psz_moviename = strdup( value );
        }
        else if( !strcmp( attrname, "playeveryframe" ) )
            b_playeveryframe = !strcmp( value, "true" );
        else if( !strcmp( attrname, "qtnext" ) )
        {
            free( psz_qtnext );
            psz_qtnext = strdup( value );
        }
        else if( !strcmp( attrname, "quitwhendone" ) )
            b_quitwhendone = !strcmp( value, "true" );
        else if( !strcmp( attrname, "src" ) )
        {
            free( psz_src );
            psz_src = strdup( value );
        }
        else if( !strcmp( attrname, "mimetype" ) )
        {
            free( psz_mimetype );
            psz_mimetype = strdup( value );
        }
        else if( !strcmp( attrname, "volume" ) )
            i_volume = atoi( value );
        else
            msg_Dbg( p_demux, "Attribute %s with value %s isn't valid",
                     attrname, value );
    }

    msg_Dbg( p_demux, "autoplay: %s (unused by VLC)",
             b_autoplay ? "true": "false" );
    msg_Dbg( p_demux, "controller: %s (unused by VLC)",
             b_controller ? "true": "false" );
    msg_Dbg( p_demux, "fullscreen: %s (unused by VLC)",
             ppsz_fullscreen[fullscreen] );
    msg_Dbg( p_demux, "href: %s", psz_href );
    msg_Dbg( p_demux, "kioskmode: %s (unused by VLC)",
             b_kioskmode ? "true":"false" );
    msg_Dbg( p_demux, "loop: %s (unused by VLC)", ppsz_loop[loop] );
    msg_Dbg( p_demux, "movieid: %d (unused by VLC)", i_movieid );
    msg_Dbg( p_demux, "moviename: %s", psz_moviename );
    msg_Dbg( p_demux, "playeverframe: %s (unused by VLC)",
             b_playeveryframe ? "true":"false" );
    msg_Dbg( p_demux, "qtnext: %s", psz_qtnext );
    msg_Dbg( p_demux, "quitwhendone: %s (unused by VLC)",
             b_quitwhendone ? "true":"false" );
    msg_Dbg( p_demux, "src: %s", psz_src );
    msg_Dbg( p_demux, "mimetype: %s", psz_mimetype );
    msg_Dbg( p_demux, "volume: %d (unused by VLC)", i_volume );


    if( !psz_src )
    {
        msg_Err( p_demux, "Mandatory attribute 'src' not found" );
    }
    else
    {
        p_input = input_item_New( psz_src, psz_moviename );
#define SADD_INFO( type, field ) if( field ) { input_item_AddInfo( \
                    p_input, "QuickTime Media Link", type, "%s", field ) ; }
        SADD_INFO( "href", psz_href );
        SADD_INFO( _("Mime"), psz_mimetype );
        input_item_node_AppendItem( p_subitems, p_input );
        input_item_Release( p_input );
        if( psz_qtnext )
        {
            vlc_xml_decode( psz_qtnext );
            p_input = input_item_New( psz_qtnext, NULL );
            input_item_node_AppendItem( p_subitems, p_input );
            input_item_Release( p_input );
        }
    }

    i_ret = 0; /* Needed for correct operation of go back */

error:
    if( p_xml_reader )
        xml_ReaderDelete( p_xml_reader );

    free( psz_href );
    free( psz_moviename );
    free( psz_qtnext );
    free( psz_src );
    free( psz_mimetype );
    return i_ret;
}
Beispiel #27
0
static int ParseManifest( addons_finder_t *p_finder, addon_entry_t *p_entry,
                          const char *psz_tempfile, stream_t *p_stream )
{
    int i_num_entries_created = 0;
    const char *p_node;
    int i_current_node_type;

    /* attr */
    const char *attr, *value;

    /* temp reading */
    const char *psz_filename = NULL;
    int i_filetype = -1;

    xml_reader_t *p_xml_reader = xml_ReaderCreate( p_finder, p_stream );
    if( !p_xml_reader ) return 0;

    if( xml_ReaderNextNode( p_xml_reader, &p_node ) != XML_READER_STARTELEM )
    {
        msg_Err( p_finder, "invalid xml file" );
        goto end;
    }

    if ( strcmp( p_node, "videolan") )
    {
        msg_Err( p_finder, "unsupported XML data format" );
        goto end;
    }

    while( (i_current_node_type = xml_ReaderNextNode( p_xml_reader, &p_node )) > 0 )
    {
        switch( i_current_node_type )
        {
        case XML_READER_STARTELEM:
        {
            BINDNODE("resource", psz_filename, TYPE_STRING)
            data_pointer.e_type = TYPE_NONE;

            /*
             * Manifests are not allowed to update addons properties
             * such as uuid, score, downloads, ...
             * On the other hand, repo API must not set files directly.
             */

            if ( ! strcmp( p_node, "resource" ) )
            {
                while( (attr = xml_ReaderNextAttr( p_xml_reader, &value )) )
                {
                    if ( !strcmp( attr, "type" ) )
                    {
                        i_filetype = ReadType( value );
                    }
                }
            }
            else if ( ! strcmp( p_node, "addon" ) )
            {
                while( (attr = xml_ReaderNextAttr( p_xml_reader, &value )) )
                {
                    if ( !strcmp( attr, "type" ) )
                    {
                        p_entry->e_type = ReadType( value );
                    }
                }
            }

            break;
        }
        case XML_READER_TEXT:
            if ( data_pointer.e_type == TYPE_NONE || !p_entry ) break;
            if ( data_pointer.e_type == TYPE_STRING )
                *data_pointer.u_data.ppsz = strdup( p_node );
            else
            if ( data_pointer.e_type == TYPE_LONG )
                *data_pointer.u_data.pl = atol( p_node );
            else
            if ( data_pointer.e_type == TYPE_INTEGER )
                *data_pointer.u_data.pi = atoi( p_node );
            break;

        case XML_READER_ENDELEM:

            if ( ! strcmp( p_node, "resource" ) )
            {
                if ( psz_filename && i_filetype >= 0 )
                {
                    addon_file_t *p_file = malloc( sizeof(addon_file_t) );
                    p_file->e_filetype = i_filetype;
                    p_file->psz_filename = strdup( psz_filename );
                    if ( asprintf( & p_file->psz_download_uri, "unzip://%s!/%s",
                                   psz_tempfile, psz_filename  ) > 0 )
                    {
                        ARRAY_APPEND( p_entry->files, p_file );
                        msg_Dbg( p_finder, "manifest lists file %s extractable from %s",
                                 psz_filename, p_file->psz_download_uri );
                        i_num_entries_created++;
                    }
                    else
                    {
                        free( p_file->psz_filename );
                        free( p_file );
                    }
                }
                /* reset temp */
                psz_filename = NULL;
                i_filetype = -1;
            }

            data_pointer.e_type = TYPE_NONE;
            break;

        default:
            break;
        }
    }

end:
   xml_ReaderDelete( p_xml_reader );
   return i_num_entries_created;
}
Beispiel #28
0
static mtime_t ParseTime(xml_reader_t *p_xml_reader)
{
    char *psz_value = NULL;
    char *psz_start = NULL;

    const char *psz_node = NULL;
    const char *psz_txt = NULL;

    int i_subfractions = -1;

    int i_subresult = 0;
    mtime_t i_result = 0;

    do
    {
        psz_txt = xml_ReaderNextAttr( p_xml_reader, &psz_node );
    }
    while( psz_txt && strncasecmp( psz_txt, "VALUE", 5 ) );

    psz_value = strdup( psz_node );
    psz_start = psz_value;

    while( *psz_value )
    {
        if( isdigit( *psz_value ) )
        {
            i_subresult = i_subresult * 10;
            i_subresult += *psz_value - '0';
            if( i_subfractions != -1 )
                i_subfractions++;
        }
        else if( *psz_value == ':' )
        {
            i_result += i_subresult;
            i_result = i_result * 60;
            i_subresult = 0;
        }
        else if( *psz_value == '.' )
        {
            i_subfractions = 0;
            i_result += i_subresult;
            i_subresult = 0;
        }
        psz_value++;

    }
    if( i_subfractions == -1)
        i_result += i_subresult;

    /* Convert to microseconds */
    if( i_subfractions == -1)
        i_subfractions = 0;
    while( i_subfractions < 6 )
    {
        i_subresult = i_subresult * 10;
        i_subfractions++;
    }
    i_result = i_result * 1000000;
    if( i_subfractions != -1)
        i_result += i_subresult;

    free( psz_start );
    return i_result;
}