inline static void free_all_node( node *root ) { while( root ) { free_all_node( root->child ); free( root->name ); node *tmp = root->next; free( root ); root = tmp; } }
inline static void free_all_node( node *root ) { while( root ) { free_all_node( root->child ); free( root->name ); item *media = root->media; while( media ) { item *next_media = media->next; free( media ); media = next_media; } node *tmp = root->next; free( root ); root = tmp; } }
/** ************************************************************************** * \brief Write the XSPF playlist given the list of files *****************************************************************************/ static int WriteXSPF( char **pp_buffer, vlc_array_t *p_filenames, const char *psz_zippath ) { char *psz_zip = strrchr( psz_zippath, DIR_SEP_CHAR ); psz_zip = vlc_xml_encode( psz_zip ? (psz_zip+1) : psz_zippath ); if( asprintf( pp_buffer, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<playlist version=\"1\" xmlns=\"http://xspf.org/ns/0/\" " "xmlns:vlc=\"http://www.videolan.org/vlc/playlist/ns/0/\">\n" " <title>%s</title>\n" " <trackList>\n", psz_zip ) == -1) return -1; /* Root node */ node *playlist = new_node( psz_zip ); free( psz_zip ); /* Encode the URI and append ZIP_SEP */ char *psz_pathtozip; escapeToXml( &psz_pathtozip, psz_zippath ); if( astrcatf( &psz_pathtozip, "%s", ZIP_SEP ) < 0 ) { free_all_node( playlist ); return -1; } int i_track = 0; for( int i = 0; i < vlc_array_count( p_filenames ); ++i ) { char *psz_name = (char*) vlc_array_item_at_index( p_filenames, i ); int i_len = strlen( psz_name ); if( !i_len ) continue; /* Is it a folder ? */ if( psz_name[i_len-1] == '/' ) { /* Do nothing */ } else /* File */ { /* Extract file name */ char *psz_file = strrchr( psz_name, '/' ); psz_file = vlc_xml_encode( psz_file ? (psz_file+1) : psz_name ); /* Build full MRL */ char *psz_path = strdup( psz_pathtozip ); char *psz_escapedName; escapeToXml( &psz_escapedName, psz_name ); if( astrcatf( &psz_path, "%s", psz_escapedName ) < 0 ) { free( psz_escapedName ); return -1; } free( psz_escapedName ); /* Track information */ if( astrcatf( pp_buffer, " <track>\n" " <location>zip://%s</location>\n" " <title>%s</title>\n" " <extension application=\"http://www.videolan.org/vlc/playlist/0\">\n" " <vlc:id>%d</vlc:id>\n" " </extension>\n" " </track>\n", psz_path, psz_file, i_track ) < 0 ) return -1; free( psz_file ); free( psz_path ); /* Find the parent node */ node *parent = findOrCreateParentNode( playlist, psz_name ); assert( parent ); /* Add the item to this node */ item *tmp = parent->media; if( !tmp ) { parent->media = new_item( i_track ); } else { while( tmp->next ) { tmp = tmp->next; } tmp->next = new_item( i_track ); } ++i_track; } } free( psz_pathtozip ); /* Close tracklist, open the extension */ if( astrcatf( pp_buffer, " </trackList>\n" " <extension application=\"http://www.videolan.org/vlc/playlist/0\">\n" ) < 0 ) return -1; /* Write the tree */ if( nodeToXSPF( pp_buffer, playlist, true ) < 0 ) return -1; /* Close extension and playlist */ if( astrcatf( pp_buffer, " </extension>\n</playlist>\n" ) < 0 ) return -1; /* printf( "%s", *pp_buffer ); */ free_all_node( playlist ); return VLC_SUCCESS; }