📄 itml.c
字号:
msg_Err( p_demux, "invalid xml stream" ); FREE_ATT_KEY(); return false; } /* leave if the current parent node <track> is terminated */ if( !strcmp( psz_name, psz_element ) ) { FREE_ATT_KEY(); return true; } /* there MUST have been a start tag for that element name */ if( !p_handler || !p_handler->name || strcmp( p_handler->name, psz_name )) { msg_Err( p_demux, "there's no open element left for <%s>", psz_name ); FREE_ATT_KEY(); return false; } /* special case: key */ if( !strcmp( p_handler->name, "key" ) ) { psz_key = strdup( psz_value ); } /* call the simple handler */ else if( p_handler->pf_handler.smpl ) { p_handler->pf_handler.smpl( p_track, psz_key, psz_value ); } FREE_ATT(); p_handler = NULL; break; default: /* unknown/unexpected xml node */ msg_Err( p_demux, "unexpected xml node %i", i_node ); FREE_ATT_KEY(); return false; } FREE_NAME(); } msg_Err( p_demux, "unexpected end of xml data" ); FREE_ATT_KEY(); return false;}static bool parse_plist_dict COMPLEX_INTERFACE{ VLC_UNUSED(p_track); VLC_UNUSED(psz_element); VLC_UNUSED(p_handlers); xml_elem_hnd_t pl_elements[] = { {"dict", COMPLEX_CONTENT, {.cmplx = parse_tracks_dict} }, {"array", SIMPLE_CONTENT, {NULL} }, {"key", SIMPLE_CONTENT, {NULL} }, {"integer", SIMPLE_CONTENT, {NULL} }, {"string", SIMPLE_CONTENT, {NULL} }, {"date", SIMPLE_CONTENT, {NULL} }, {"true", SIMPLE_CONTENT, {NULL} }, {"false", SIMPLE_CONTENT, {NULL} }, {NULL, UNKNOWN_CONTENT, {NULL} } }; return parse_dict( p_demux, p_input_item, NULL, p_xml_reader, "dict", pl_elements );}static bool parse_tracks_dict COMPLEX_INTERFACE{ VLC_UNUSED(p_track); VLC_UNUSED(psz_element); VLC_UNUSED(p_handlers); xml_elem_hnd_t tracks_elements[] = { {"dict", COMPLEX_CONTENT, {.cmplx = parse_track_dict} }, {"key", SIMPLE_CONTENT, {NULL} }, {NULL, UNKNOWN_CONTENT, {NULL} } }; parse_dict( p_demux, p_input_item, NULL, p_xml_reader, "dict", tracks_elements ); msg_Info( p_demux, "added %i tracks successfully", p_demux->p_sys->i_ntracks ); return true;}static bool parse_track_dict COMPLEX_INTERFACE{ VLC_UNUSED(psz_element); VLC_UNUSED(p_handlers); input_item_t *p_new_input = NULL; int i_ret = -1; char *psz_uri = NULL; p_track = new_track(); xml_elem_hnd_t track_elements[] = { {"array", COMPLEX_CONTENT, {.cmplx = skip_element} }, {"key", SIMPLE_CONTENT, {.smpl = save_data} }, {"integer", SIMPLE_CONTENT, {.smpl = save_data} }, {"string", SIMPLE_CONTENT, {.smpl = save_data} }, {"date", SIMPLE_CONTENT, {.smpl = save_data} }, {"true", SIMPLE_CONTENT, {NULL} }, {"false", SIMPLE_CONTENT, {NULL} }, {NULL, UNKNOWN_CONTENT, {NULL} } }; i_ret = parse_dict( p_demux, p_input_item, p_track, p_xml_reader, "dict", track_elements ); msg_Dbg( p_demux, "name: %s, artist: %s, album: %s, genre: %s, trackNum: %s, location: %s", p_track->name, p_track->artist, p_track->album, p_track->genre, p_track->trackNum, p_track->location ); if( !p_track->location ) { msg_Err( p_demux, "Track needs Location" ); free_track( p_track ); return false; } psz_uri = decode_URI_duplicate( p_track->location ); if( psz_uri ) { if( strlen( psz_uri ) > 17 && !strncmp( psz_uri, "file://localhost/", 17 ) ) { /* remove 'localhost/' */ memmove( psz_uri + 7, psz_uri + 17, strlen( psz_uri ) - 9 ); msg_Info( p_demux, "Adding '%s'", psz_uri ); p_new_input = input_item_NewExt( p_demux, psz_uri, NULL, 0, NULL, -1 ); input_item_AddSubItem( p_input_item, p_new_input ); /* add meta info */ add_meta( p_new_input, p_track ); vlc_gc_decref( p_new_input ); p_demux->p_sys->i_ntracks++; } else { msg_Err( p_demux, "Don't know how to handle %s", psz_uri ); } free( psz_uri ); } free_track( p_track ); return i_ret;}static track_elem_t *new_track(){ track_elem_t *p_track = NULL; p_track = (track_elem_t *)malloc( sizeof( track_elem_t ) ); if( p_track ) { p_track->name = NULL; p_track->artist = NULL; p_track->album = NULL; p_track->genre = NULL; p_track->trackNum = NULL; p_track->location = NULL; p_track->duration = 0; } return p_track;}static void free_track( track_elem_t *p_track ){ fprintf( stderr, "free track\n" ); if ( !p_track ) return; FREE( p_track->name ) FREE( p_track->artist ) FREE( p_track->album ) FREE( p_track->genre ) FREE( p_track->trackNum ) FREE( p_track->location ) p_track->duration = 0; free( p_track );}static bool save_data SIMPLE_INTERFACE{ /* exit if setting is impossible */ if( !psz_name || !psz_value || !p_track ) return false; /* re-convert xml special characters inside psz_value */ resolve_xml_special_chars( psz_value );#define SAVE_INFO( name, value ) \ if( !strcmp( psz_name, name ) ) { p_track->value = strdup( psz_value ); } SAVE_INFO( "Name", name ) else SAVE_INFO( "Artist", artist ) else SAVE_INFO( "Album", album ) else SAVE_INFO( "Genre", genre ) else SAVE_INFO( "Track Number", trackNum ) else SAVE_INFO( "Location", location ) else if( !strcmp( psz_name, "Total Time" ) ) { long i_num = atol( psz_value ); p_track->duration = (mtime_t) i_num*1000; } return true;}/** * \brief handles the supported <track> sub-elements */static bool add_meta( input_item_t *p_input_item, track_elem_t *p_track ){ /* exit if setting is impossible */ if( !p_input_item || !p_track ) return false;#define SET_INFO( func, prop ) \ if( p_track->prop ) { func( p_input_item, p_track->prop ); } SET_INFO( input_item_SetTitle, name ) SET_INFO( input_item_SetArtist, artist ) SET_INFO( input_item_SetAlbum, album ) SET_INFO( input_item_SetGenre, genre ) SET_INFO( input_item_SetTrackNum, trackNum ) SET_INFO( input_item_SetDuration, duration ) return true;}/** * \brief skips complex element content that we can't manage */static bool skip_element COMPLEX_INTERFACE{ VLC_UNUSED(p_demux); VLC_UNUSED(p_input_item); VLC_UNUSED(p_track); VLC_UNUSED(p_handlers); 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 false; if( !strcmp( psz_element, psz_endname ) ) { free( psz_endname ); return true; } else free( psz_endname ); } } return false;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -