📄 xspf.c
字号:
if ( !psz_name ) { msg_Err( p_demux, "unexpected end of xml data" ); FREE_NAME(); return VLC_FALSE; } if ( strcmp( psz_name, "track") ) { msg_Err( p_demux, "unexpected child of <trackList>: <%s>", psz_name ); FREE_NAME(); return VLC_FALSE; } FREE_NAME(); /* parse the track data in a separate function */ if ( parse_track_node( p_demux, p_playlist, p_item, p_xml_reader, "track" ) == VLC_TRUE ) i_ntracks++; } else if ( i_node == XML_READER_ENDELEM ) break; } /* the <trackList> has to be terminated */ if ( xml_ReaderNodeType( p_xml_reader ) != XML_READER_ENDELEM ) { msg_Err( p_demux, "there's a missing </trackList>" ); FREE_NAME(); return VLC_FALSE; } psz_name = xml_ReaderName( p_xml_reader ); if ( !psz_name || strcmp( psz_name, "trackList" ) ) { msg_Err( p_demux, "expected: </trackList>, found: </%s>", psz_name ); FREE_NAME(); return VLC_FALSE; } FREE_NAME(); msg_Dbg( p_demux, "parsed %i tracks successfully", i_ntracks ); return VLC_TRUE;}/** * \brief parse one track element * \param COMPLEX_INTERFACE */static vlc_bool_t parse_track_node COMPLEX_INTERFACE{ playlist_item_t *p_new=NULL; int i_node; char *psz_name=NULL; char *psz_value=NULL; xml_elem_hnd_t *p_handler=NULL; xml_elem_hnd_t track_elements[] = { {"location", SIMPLE_CONTENT, {NULL} }, {"identifier", SIMPLE_CONTENT, {NULL} }, {"title", SIMPLE_CONTENT, {.smpl = set_item_info} }, {"creator", SIMPLE_CONTENT, {.smpl = set_item_info} }, {"annotation", SIMPLE_CONTENT, {NULL} }, {"info", SIMPLE_CONTENT, {NULL} }, {"image", SIMPLE_CONTENT, {NULL} }, {"album", SIMPLE_CONTENT, {.smpl = set_item_info} }, {"trackNum", SIMPLE_CONTENT, {.smpl = set_item_info} }, {"duration", SIMPLE_CONTENT, {.smpl = set_item_info} }, {"link", SIMPLE_CONTENT, {NULL} }, {"meta", SIMPLE_CONTENT, {NULL} }, {"extension", COMPLEX_CONTENT, {.cmplx = skip_element} }, {NULL, UNKNOWN_CONTENT, {NULL} } }; while ( xml_ReaderRead( p_xml_reader ) == 1 ) { i_node = xml_ReaderNodeType( p_xml_reader ); switch ( i_node ) { case XML_READER_NONE: break; case XML_READER_STARTELEM: /* element start tag */ psz_name = xml_ReaderName( p_xml_reader ); if ( !psz_name || !*psz_name ) { msg_Err( p_demux, "invalid xml stream" ); FREE_ATT(); return VLC_FALSE; } /* choose handler */ for( p_handler = track_elements; p_handler->name && strcmp( psz_name, p_handler->name ); p_handler++ ); if ( !p_handler->name ) { msg_Err( p_demux, "unexpected element <%s>", psz_name ); FREE_ATT(); return VLC_FALSE; } FREE_NAME(); /* complex content is parsed in a separate function */ if ( p_handler->type == COMPLEX_CONTENT ) { if ( !p_new ) { msg_Err( p_demux, "at <%s> level no new item has been allocated", p_handler->name ); FREE_ATT(); return VLC_FALSE; } if ( p_handler->pf_handler.cmplx( p_demux, p_playlist, p_new, p_xml_reader, p_handler->name ) ) { p_handler = NULL; FREE_ATT(); } else { FREE_ATT(); return VLC_FALSE; } } break; case XML_READER_TEXT: /* simple element content */ FREE_ATT(); psz_value = xml_ReaderValue( p_xml_reader ); if ( !psz_value ) { msg_Err( p_demux, "invalid xml stream" ); FREE_ATT(); return VLC_FALSE; } break; case XML_READER_ENDELEM: /* element end tag */ psz_name = xml_ReaderName( p_xml_reader ); if ( !psz_name ) { msg_Err( p_demux, "invalid xml stream" ); FREE_ATT(); return VLC_FALSE; } /* leave if the current parent node <track> is terminated */ if ( !strcmp( psz_name, psz_element ) ) { FREE_ATT(); return VLC_TRUE; } /* there MUST have been a start tag for that element name */ if ( !p_handler || !p_handler->name || strcmp( p_handler->name, psz_name )) { msg_Err( p_demux, "there's no open element left for <%s>", psz_name ); FREE_ATT(); return VLC_FALSE; } /* special case: location */ if ( !strcmp( p_handler->name, "location" ) ) { /* there MUST NOT be an item */ if ( p_new ) { msg_Err( p_demux, "a new item has just been created <%s>", psz_name ); FREE_ATT(); return VLC_FALSE; } /* create it now */ if ( insert_new_item( p_playlist, p_item, &p_new, psz_value ) ) { FREE_ATT(); p_handler = NULL; } else { FREE_ATT(); return VLC_FALSE; } } else { /* there MUST be an item */ if ( !p_new ) { msg_Err( p_demux, "an item hasn't been created yet <%s>", psz_name ); FREE_ATT(); return VLC_FALSE; } if ( p_handler->pf_handler.smpl ) { p_handler->pf_handler.smpl( p_new, p_handler->name, psz_value ); FREE_ATT(); } } FREE_ATT(); p_handler = NULL; break; default: /* unknown/unexpected xml node */ msg_Err( p_demux, "unexpected xml node %i", i_node ); FREE_ATT(); return VLC_FALSE; } FREE_NAME(); } msg_Err( p_demux, "unexpected end of xml data" ); FREE_ATT(); return VLC_FALSE;}/** * \brief handles the supported <track> sub-elements */static vlc_bool_t set_item_info SIMPLE_INTERFACE{ /* exit if setting is impossible */ if ( !psz_name || !psz_value || !p_item ) return VLC_FALSE; /* re-convert xml special characters inside psz_value */ resolve_xml_special_chars ( psz_value ); /* handle each info element in a separate "if" clause */ if ( !strcmp( psz_name, "title" ) ) { if ( playlist_ItemSetName ( p_item, (char *)psz_value ) == VLC_SUCCESS ) return VLC_TRUE; return VLC_FALSE; } else if ( !strcmp( psz_name, "creator" ) ) { if ( vlc_input_item_AddInfo( &(p_item->input), _(VLC_META_INFO_CAT), _(VLC_META_ARTIST), "%s", psz_value ) == VLC_SUCCESS ) return VLC_TRUE; return VLC_FALSE; } else if ( !strcmp( psz_name, "album" ) ) { if ( vlc_input_item_AddInfo( &(p_item->input), _(VLC_META_INFO_CAT), _(VLC_META_COLLECTION), "%s", psz_value ) == VLC_SUCCESS ) return VLC_TRUE; return VLC_FALSE; } else if ( !strcmp( psz_name, "trackNum" ) ) { long i_num = atol( psz_value ); if ( i_num > 0 && vlc_input_item_AddInfo( &(p_item->input), _(VLC_META_INFO_CAT), _(VLC_META_SEQ_NUM), "%s", psz_value ) == VLC_SUCCESS ) return VLC_TRUE; return VLC_FALSE; } else if ( !strcmp( psz_name, "duration" ) ) { long i_num = atol( psz_value ); if ( i_num > 0 && playlist_ItemSetDuration( p_item, i_num*1000 ) == VLC_SUCCESS ) return VLC_TRUE; return VLC_FALSE; } return VLC_TRUE;}/** * \brief skips complex element content that we can't manage */static vlc_bool_t skip_element COMPLEX_INTERFACE{ char *psz_endname; while ( xml_ReaderRead( p_xml_reader ) == 1 ) { if ( xml_ReaderNodeType( p_xml_reader ) == XML_READER_ENDELEM ) { psz_endname = xml_ReaderName( p_xml_reader ); if ( !psz_endname ) return VLC_FALSE; if ( !strcmp( psz_element, psz_endname ) ) { free( psz_endname ); return VLC_TRUE; } else free( psz_endname ); } } return VLC_FALSE;}/** * \brief creates a new playlist item from the given mrl */static vlc_bool_t insert_new_item( playlist_t *p_pl, playlist_item_t *p_cur, playlist_item_t **pp_new, char *psz_location ){ char *psz_uri=NULL; psz_uri = decode_URI_duplicate( psz_location ); if ( psz_uri ) { *pp_new = playlist_ItemNew( p_pl, psz_uri, NULL ); free( psz_uri ); psz_uri = NULL; } if ( !*pp_new ) return VLC_FALSE; playlist_NodeAddItem( p_pl, *pp_new, p_cur->pp_parents[0]->i_view, p_cur, PLAYLIST_APPEND, PLAYLIST_END ); playlist_CopyParents( p_cur, *pp_new ); vlc_input_item_CopyOptions( &p_cur->input, &((*pp_new)->input) ); return VLC_TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -