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 "debug.h"
24 #include "i18n.h"
25 #include "misc.h"
26 #include "playlist.h"
27 #include "plugin.h"
28 #include "plugins.h"
29 
30 static PluginHandle * get_plugin_silent (const char * filename)
31 {
32  char buf[32];
33  if (! uri_get_extension (filename, buf, sizeof buf))
34  return NULL;
35 
36  return playlist_plugin_for_extension (buf);
37 }
38 
40 {
41  return (get_plugin_silent (filename) != NULL);
42 }
43 
44 static PluginHandle * get_plugin (const char * filename, bool_t saving)
45 {
46  PluginHandle * plugin = get_plugin_silent (filename);
47 
48  if (! plugin)
49  {
50  char * error = str_printf (_("Cannot %s %s: unsupported file "
51  "extension."), saving ? _("save") : _("load"), filename);
52  interface_show_error (error);
53  str_unref (error);
54  return NULL;
55  }
56 
57  return plugin;
58 }
59 
60 bool_t playlist_load (const char * filename, char * * title,
61  Index * * filenames_p, Index * * tuples_p)
62 {
63  AUDDBG ("Loading playlist %s.\n", filename);
64 
65  PluginHandle * plugin = get_plugin (filename, FALSE);
66  if (! plugin)
67  return FALSE;
68 
69  PlaylistPlugin * pp = plugin_get_header (plugin);
70  g_return_val_if_fail (pp && PLUGIN_HAS_FUNC (pp, load), FALSE);
71 
72  VFSFile * file = vfs_fopen (filename, "r");
73  if (! file)
74  return FALSE;
75 
76  Index * filenames = index_new ();
77  Index * tuples = index_new ();
78  bool_t success = pp->load (filename, file, title, filenames, tuples);
79 
80  vfs_fclose (file);
81 
82  if (! success)
83  {
84  index_free (filenames);
85  index_free (tuples);
86  return FALSE;
87  }
88 
89  if (index_count (tuples))
90  g_return_val_if_fail (index_count (tuples) == index_count (filenames),
91  FALSE);
92  else
93  {
94  index_free (tuples);
95  tuples = NULL;
96  }
97 
98  * filenames_p = filenames;
99  * tuples_p = tuples;
100  return TRUE;
101 }
102 
104  const char * filename)
105 {
106  char * title = NULL;
107  Index * filenames, * tuples;
108 
109  if (! playlist_load (filename, & title, & filenames, & tuples))
110  return FALSE;
111 
112  if (title && ! playlist_entry_count (list))
113  playlist_set_title (list, title);
114 
115  playlist_entry_insert_batch_raw (list, at, filenames, tuples, NULL);
116 
117  str_unref (title);
118  return TRUE;
119 }
120 
121 bool_t playlist_save (int list, const char * filename)
122 {
123  AUDDBG ("Saving playlist %s.\n", filename);
124 
125  PluginHandle * plugin = get_plugin (filename, TRUE);
126  if (! plugin)
127  return FALSE;
128 
129  PlaylistPlugin * pp = plugin_get_header (plugin);
130  g_return_val_if_fail (pp && PLUGIN_HAS_FUNC (pp, load), FALSE);
131 
132  bool_t fast = get_bool (NULL, "metadata_on_play");
133 
134  VFSFile * file = vfs_fopen (filename, "w");
135  if (! file)
136  return FALSE;
137 
138  char * title = playlist_get_title (list);
139 
140  int entries = playlist_entry_count (list);
141  Index * filenames = index_new ();
142  index_allocate (filenames, entries);
143  Index * tuples = index_new ();
144  index_allocate (tuples, entries);
145 
146  for (int i = 0; i < entries; i ++)
147  {
148  index_append (filenames, playlist_entry_get_filename (list, i));
149  index_append (tuples, playlist_entry_get_tuple (list, i, fast));
150  }
151 
152  bool_t success = pp->save (filename, file, title, filenames, tuples);
153 
154  vfs_fclose (file);
155  str_unref (title);
156 
157  for (int i = 0; i < entries; i ++)
158  {
159  str_unref (index_get (filenames, i));
160  Tuple * tuple = index_get (tuples, i);
161  if (tuple)
162  tuple_unref (tuple);
163  }
164 
165  index_free (filenames);
166  index_free (tuples);
167 
168  return success;
169 }