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  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions, and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions, and the following disclaimer in the documentation
13  * provided with the distribution.
14  *
15  * This software is provided "as is" and without any warranty, express or
16  * implied. In no event shall the authors be liable for any damages arising from
17  * the use of this software.
18  */
19 
20 #include <glib.h>
21 #include <libaudcore/audstrings.h>
22 
23 #include "config.h"
24 #include "debug.h"
25 #include "i18n.h"
26 #include "misc.h"
27 #include "playlist.h"
28 #include "plugin.h"
29 #include "plugins.h"
30 
31 static PluginHandle * get_plugin_silent (const char * filename)
32 {
33  char buf[32];
34  if (! uri_get_extension (filename, buf, sizeof buf))
35  return NULL;
36 
37  return playlist_plugin_for_extension (buf);
38 }
39 
41 {
42  return (get_plugin_silent (filename) != NULL);
43 }
44 
45 static PluginHandle * get_plugin (const char * filename, bool_t saving)
46 {
47  PluginHandle * plugin = get_plugin_silent (filename);
48 
49  if (! plugin)
50  {
51  char * error = str_printf (_("Cannot %s %s: unsupported file "
52  "extension."), saving ? _("save") : _("load"), filename);
53  interface_show_error (error);
54  str_unref (error);
55  return NULL;
56  }
57 
58  return plugin;
59 }
60 
61 bool_t playlist_load (const char * filename, char * * title,
62  Index * * filenames_p, Index * * tuples_p)
63 {
64  AUDDBG ("Loading playlist %s.\n", filename);
65 
66  PluginHandle * plugin = get_plugin (filename, FALSE);
67  if (! plugin)
68  return FALSE;
69 
70  PlaylistPlugin * pp = plugin_get_header (plugin);
71  g_return_val_if_fail (pp && PLUGIN_HAS_FUNC (pp, load), FALSE);
72 
73  VFSFile * file = vfs_fopen (filename, "r");
74  if (! file)
75  return FALSE;
76 
77  Index * filenames = index_new ();
78  Index * tuples = index_new ();
79  bool_t success = pp->load (filename, file, title, filenames, tuples);
80 
81  vfs_fclose (file);
82 
83  if (! success)
84  {
85  index_free (filenames);
86  index_free (tuples);
87  return FALSE;
88  }
89 
90  if (index_count (tuples))
91  g_return_val_if_fail (index_count (tuples) == index_count (filenames),
92  FALSE);
93  else
94  {
95  index_free (tuples);
96  tuples = NULL;
97  }
98 
99  * filenames_p = filenames;
100  * tuples_p = tuples;
101  return TRUE;
102 }
103 
105  const char * filename)
106 {
107  char * title = NULL;
108  Index * filenames, * tuples;
109 
110  if (! playlist_load (filename, & title, & filenames, & tuples))
111  return FALSE;
112 
113  if (title && ! playlist_entry_count (list))
114  playlist_set_title (list, title);
115 
116  playlist_entry_insert_batch_raw (list, at, filenames, tuples, NULL);
117 
118  str_unref (title);
119  return TRUE;
120 }
121 
122 bool_t playlist_save (int list, const char * filename)
123 {
124  AUDDBG ("Saving playlist %s.\n", filename);
125 
126  PluginHandle * plugin = get_plugin (filename, TRUE);
127  if (! plugin)
128  return FALSE;
129 
130  PlaylistPlugin * pp = plugin_get_header (plugin);
131  g_return_val_if_fail (pp && PLUGIN_HAS_FUNC (pp, load), FALSE);
132 
133  bool_t fast = get_bool (NULL, "metadata_on_play");
134 
135  VFSFile * file = vfs_fopen (filename, "w");
136  if (! file)
137  return FALSE;
138 
139  char * title = playlist_get_title (list);
140 
141  int entries = playlist_entry_count (list);
142  Index * filenames = index_new ();
143  index_allocate (filenames, entries);
144  Index * tuples = index_new ();
145  index_allocate (tuples, entries);
146 
147  for (int i = 0; i < entries; i ++)
148  {
149  index_append (filenames, playlist_entry_get_filename (list, i));
150  index_append (tuples, playlist_entry_get_tuple (list, i, fast));
151  }
152 
153  bool_t success = pp->save (filename, file, title, filenames, tuples);
154 
155  vfs_fclose (file);
156  str_unref (title);
157 
158  for (int i = 0; i < entries; i ++)
159  {
160  str_unref (index_get (filenames, i));
161  Tuple * tuple = index_get (tuples, i);
162  if (tuple)
163  tuple_unref (tuple);
164  }
165 
166  index_free (filenames);
167  index_free (tuples);
168 
169  return success;
170 }