00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "debug.h"
00023 #include "playlist.h"
00024 #include "plugin.h"
00025 #include "plugins.h"
00026
00027 static const gchar * get_extension (const gchar * filename, gboolean quiet)
00028 {
00029 const gchar * s = strrchr (filename, '/');
00030 if (! s)
00031 goto FAIL;
00032
00033 const gchar * p = strrchr (s + 1, '.');
00034 if (! p)
00035 goto FAIL;
00036
00037 return p + 1;
00038
00039 FAIL:
00040 if (! quiet)
00041 fprintf (stderr, "Failed to parse playlist filename %s.\n", filename);
00042 return NULL;
00043 }
00044
00045 gboolean filename_is_playlist (const gchar * filename)
00046 {
00047 const gchar * ext = get_extension (filename, TRUE);
00048 if (! ext)
00049 return FALSE;
00050
00051 return playlist_plugin_for_extension (ext) ? TRUE : FALSE;
00052 }
00053
00054 static PlaylistPlugin * get_plugin (const gchar * filename)
00055 {
00056 const gchar * ext = get_extension (filename, FALSE);
00057 if (! ext)
00058 return NULL;
00059
00060 PluginHandle * plugin = playlist_plugin_for_extension (ext);
00061 if (! plugin)
00062 {
00063 fprintf (stderr, "Unrecognized playlist file type \"%s\".\n", ext);
00064 return NULL;
00065 }
00066
00067 return plugin_get_header (plugin);
00068 }
00069
00070 gboolean playlist_load (const gchar * filename, gchar * * title,
00071 struct index * * filenames_p, struct index * * tuples_p)
00072 {
00073 AUDDBG ("Loading playlist %s.\n", filename);
00074 PlaylistPlugin * pp = get_plugin (filename);
00075 g_return_val_if_fail (pp && PLUGIN_HAS_FUNC (pp, load), FALSE);
00076
00077 VFSFile * file = vfs_fopen (filename, "r");
00078 if (! file)
00079 return FALSE;
00080
00081 struct index * filenames = index_new ();
00082 struct index * tuples = index_new ();
00083 gboolean success = pp->load (filename, file, title, filenames, tuples);
00084
00085 vfs_fclose (file);
00086
00087 if (! success)
00088 {
00089 index_free (filenames);
00090 index_free (tuples);
00091 return FALSE;
00092 }
00093
00094 if (index_count (tuples))
00095 g_return_val_if_fail (index_count (tuples) == index_count (filenames),
00096 FALSE);
00097 else
00098 {
00099 index_free (tuples);
00100 tuples = NULL;
00101 }
00102
00103 * filenames_p = filenames;
00104 * tuples_p = tuples;
00105 return TRUE;
00106 }
00107
00108 gboolean playlist_insert_playlist_raw (gint list, gint at,
00109 const gchar * filename)
00110 {
00111 gchar * title = NULL;
00112 struct index * filenames, * tuples;
00113
00114 if (! playlist_load (filename, & title, & filenames, & tuples))
00115 return FALSE;
00116
00117 if (title && ! playlist_entry_count (list))
00118 playlist_set_title (list, title);
00119
00120 playlist_entry_insert_batch_raw (list, at, filenames, tuples, NULL);
00121
00122 g_free (title);
00123 return TRUE;
00124 }
00125
00126 gboolean playlist_save (gint list, const gchar * filename)
00127 {
00128 AUDDBG ("Saving playlist %s.\n", filename);
00129 PlaylistPlugin * pp = get_plugin (filename);
00130 g_return_val_if_fail (pp && PLUGIN_HAS_FUNC (pp, save), FALSE);
00131
00132 VFSFile * file = vfs_fopen (filename, "w");
00133 if (! file)
00134 return FALSE;
00135
00136 gchar * title = playlist_get_title (list);
00137
00138 gint entries = playlist_entry_count (list);
00139 struct index * filenames = index_new ();
00140 index_allocate (filenames, entries);
00141 struct index * tuples = index_new ();
00142 index_allocate (tuples, entries);
00143
00144 for (gint i = 0; i < entries; i ++)
00145 {
00146 index_append (filenames, (void *) playlist_entry_get_filename (list, i));
00147 index_append (tuples, (void *) playlist_entry_get_tuple (list, i, FALSE));
00148 }
00149
00150 gboolean success = pp->save (filename, file, title, filenames, tuples);
00151
00152 vfs_fclose (file);
00153 g_free (title);
00154
00155 for (gint i = 0; i < entries; i ++)
00156 {
00157 g_free (index_get (filenames, i));
00158 tuple_free (index_get (tuples, i));
00159 }
00160
00161 index_free (filenames);
00162 index_free (tuples);
00163
00164 return success;
00165 }