Audacious  $Id:Doxyfile42802007-03-2104:39:00Znenolod$
playlist-files.c
Go to the documentation of this file.
1 /*
2  * playlist-files.c
3  * Copyright 2010-2011 John Lindgren
4  *
5  * This file is part of Audacious.
6  *
7  * Audacious is free software: you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License as published by the Free Software
9  * Foundation, version 2 or version 3 of the License.
10  *
11  * Audacious is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13  * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * Audacious. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * The Audacious team does not consider modular code linking to Audacious or
19  * using our public API to be a derived work.
20  */
21 
22 #include <glib.h>
23 #include <libaudcore/audstrings.h>
24 
25 #include "config.h"
26 #include "debug.h"
27 #include "i18n.h"
28 #include "misc.h"
29 #include "playlist.h"
30 #include "plugin.h"
31 #include "plugins.h"
32 
33 static const char * get_extension (const char * filename)
34 {
35  const char * ext;
36  uri_parse (filename, NULL, & ext, NULL, NULL);
37  return (ext && ext[0] == '.') ? ext + 1 : NULL;
38 }
39 
41 {
42  const char * ext = get_extension (filename);
43  return (ext && playlist_plugin_for_extension (ext)) ? TRUE : FALSE;
44 }
45 
46 static PluginHandle * get_plugin (const char * filename, bool_t saving)
47 {
48  const char * ext = get_extension (filename);
50 
51  if (! plugin)
52  {
53  char * error = str_printf (_("Cannot %s %s: unsupported file "
54  "extension."), saving ? _("save") : _("load"), filename);
55  interface_show_error (error);
56  str_unref (error);
57  return NULL;
58  }
59 
60  return plugin;
61 }
62 
63 bool_t playlist_load (const char * filename, char * * title,
64  Index * * filenames_p, Index * * tuples_p)
65 {
66  AUDDBG ("Loading playlist %s.\n", filename);
67 
68  PluginHandle * plugin = get_plugin (filename, FALSE);
69  if (! plugin)
70  return FALSE;
71 
72  PlaylistPlugin * pp = plugin_get_header (plugin);
73  g_return_val_if_fail (pp && PLUGIN_HAS_FUNC (pp, load), FALSE);
74 
75  VFSFile * file = vfs_fopen (filename, "r");
76  if (! file)
77  return FALSE;
78 
79  Index * filenames = index_new ();
80  Index * tuples = index_new ();
81  bool_t success = pp->load (filename, file, title, filenames, tuples);
82 
83  vfs_fclose (file);
84 
85  if (! success)
86  {
87  index_free (filenames);
88  index_free (tuples);
89  return FALSE;
90  }
91 
92  if (index_count (tuples))
93  g_return_val_if_fail (index_count (tuples) == index_count (filenames),
94  FALSE);
95  else
96  {
97  index_free (tuples);
98  tuples = NULL;
99  }
100 
101  * filenames_p = filenames;
102  * tuples_p = tuples;
103  return TRUE;
104 }
105 
107  const char * filename)
108 {
109  char * title = NULL;
110  Index * filenames, * tuples;
111 
112  if (! playlist_load (filename, & title, & filenames, & tuples))
113  return FALSE;
114 
115  if (title && ! playlist_entry_count (list))
116  playlist_set_title (list, title);
117 
118  playlist_entry_insert_batch_raw (list, at, filenames, tuples, NULL);
119 
120  str_unref (title);
121  return TRUE;
122 }
123 
124 bool_t playlist_save (int list, const char * filename)
125 {
126  AUDDBG ("Saving playlist %s.\n", filename);
127 
128  PluginHandle * plugin = get_plugin (filename, TRUE);
129  if (! plugin)
130  return FALSE;
131 
132  PlaylistPlugin * pp = plugin_get_header (plugin);
133  g_return_val_if_fail (pp && PLUGIN_HAS_FUNC (pp, load), FALSE);
134 
135  bool_t fast = get_bool (NULL, "metadata_on_play");
136 
137  VFSFile * file = vfs_fopen (filename, "w");
138  if (! file)
139  return FALSE;
140 
141  char * title = playlist_get_title (list);
142 
143  int entries = playlist_entry_count (list);
144  Index * filenames = index_new ();
145  index_allocate (filenames, entries);
146  Index * tuples = index_new ();
147  index_allocate (tuples, entries);
148 
149  for (int i = 0; i < entries; i ++)
150  {
151  index_append (filenames, playlist_entry_get_filename (list, i));
152  index_append (tuples, playlist_entry_get_tuple (list, i, fast));
153  }
154 
155  bool_t success = pp->save (filename, file, title, filenames, tuples);
156 
157  vfs_fclose (file);
158  str_unref (title);
159 
160  for (int i = 0; i < entries; i ++)
161  {
162  str_unref (index_get (filenames, i));
163  Tuple * tuple = index_get (tuples, i);
164  if (tuple)
165  tuple_unref (tuple);
166  }
167 
168  index_free (filenames);
169  index_free (tuples);
170 
171  return success;
172 }