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  SPRINTF (error, _("Cannot %s %s: unsupported file extension."),
51  saving ? _("save") : _("load"), filename);
53  return NULL;
54  }
55 
56  return plugin;
57 }
58 
59 bool_t playlist_load (const char * filename, char * * title,
60  Index * * filenames_p, Index * * tuples_p)
61 {
62  AUDDBG ("Loading playlist %s.\n", filename);
63 
64  PluginHandle * plugin = get_plugin (filename, FALSE);
65  if (! plugin)
66  return FALSE;
67 
68  PlaylistPlugin * pp = plugin_get_header (plugin);
69  g_return_val_if_fail (pp && PLUGIN_HAS_FUNC (pp, load), FALSE);
70 
71  VFSFile * file = vfs_fopen (filename, "r");
72  if (! file)
73  return FALSE;
74 
75  Index * filenames = index_new ();
76  Index * tuples = index_new ();
77  bool_t success = pp->load (filename, file, title, filenames, tuples);
78 
79  vfs_fclose (file);
80 
81  if (! success)
82  {
83  index_free (filenames);
84  index_free (tuples);
85  return FALSE;
86  }
87 
88  if (index_count (tuples))
89  g_return_val_if_fail (index_count (tuples) == index_count (filenames),
90  FALSE);
91  else
92  {
93  index_free (tuples);
94  tuples = NULL;
95  }
96 
97  * filenames_p = filenames;
98  * tuples_p = tuples;
99  return TRUE;
100 }
101 
103  const char * filename)
104 {
105  char * title = NULL;
106  Index * filenames, * tuples;
107 
108  if (! playlist_load (filename, & title, & filenames, & tuples))
109  return FALSE;
110 
111  if (title && ! playlist_entry_count (list))
112  playlist_set_title (list, title);
113 
114  playlist_entry_insert_batch_raw (list, at, filenames, tuples, NULL);
115 
116  str_unref (title);
117  return TRUE;
118 }
119 
120 bool_t playlist_save (int list, const char * filename)
121 {
122  AUDDBG ("Saving playlist %s.\n", filename);
123 
124  PluginHandle * plugin = get_plugin (filename, TRUE);
125  if (! plugin)
126  return FALSE;
127 
128  PlaylistPlugin * pp = plugin_get_header (plugin);
129  g_return_val_if_fail (pp, FALSE);
130 
131  if (! PLUGIN_HAS_FUNC (pp, save))
132  {
133  SPRINTF (error, _("Cannot save %s: plugin does not support saving."), filename);
135  return FALSE;
136  }
137 
138  bool_t fast = get_bool (NULL, "metadata_on_play");
139 
140  VFSFile * file = vfs_fopen (filename, "w");
141  if (! file)
142  return FALSE;
143 
144  char * title = playlist_get_title (list);
145 
146  int entries = playlist_entry_count (list);
147  Index * filenames = index_new ();
148  index_allocate (filenames, entries);
149  Index * tuples = index_new ();
150  index_allocate (tuples, entries);
151 
152  for (int i = 0; i < entries; i ++)
153  {
154  index_append (filenames, playlist_entry_get_filename (list, i));
155  index_append (tuples, playlist_entry_get_tuple (list, i, fast));
156  }
157 
158  bool_t success = pp->save (filename, file, title, filenames, tuples);
159 
160  vfs_fclose (file);
161  str_unref (title);
162 
163  for (int i = 0; i < entries; i ++)
164  {
165  str_unref (index_get (filenames, i));
166  Tuple * tuple = index_get (tuples, i);
167  if (tuple)
168  tuple_unref (tuple);
169  }
170 
171  index_free (filenames);
172  index_free (tuples);
173 
174  return success;
175 }
bool_t(* load)(const char *path, VFSFile *file, char **title, Index *filenames, Index *tuples)
Definition: plugin.h:148
static PluginHandle * get_plugin(const char *filename, bool_t saving)
EXPORT Index * index_new(void)
Definition: index.c:41
const char filename
Definition: misc-api.h:85
#define _(String)
Definition: i18n.h:25
void playlist_entry_insert_batch_raw(int playlist_num, int at, Index *filenames, Index *tuples, Index *decoders)
Definition: playlist-new.c:993
EXPORT int vfs_fclose(VFSFile *file)
Closes a VFS stream and destroys a VFSFile object.
Definition: vfs.c:164
static PluginHandle * get_plugin_silent(const char *filename)
#define PLUGIN_HAS_FUNC(p, func)
Definition: plugin.h:515
int playlist_entry_count(int playlist_num)
Definition: playlist-new.c:986
EXPORT int index_count(Index *index)
Definition: index.c:58
#define FALSE
Definition: core.h:35
PluginHandle * playlist_plugin_for_extension(const char *extension)
Index Index bool_t
Definition: playlist-api.h:122
#define AUDDBG(...)
Definition: debug.h:30
EXPORT void index_allocate(Index *index, int size)
Definition: index.c:63
const void * plugin_get_header(PluginHandle *plugin)
bool_t filename_is_playlist(const char *filename)
bool_t playlist_insert_playlist_raw(int list, int at, const char *filename)
Tuple * playlist_entry_get_tuple(int playlist_num, int entry_num, bool_t fast)
char * playlist_get_title(int playlist_num)
Definition: playlist-new.c:822
#define NULL
Definition: core.h:27
EXPORT void * index_get(Index *index, int at)
Definition: index.c:82
EXPORT void index_append(Index *index, void *value)
Definition: index.c:104
EXPORT void tuple_unref(Tuple *tuple)
Definition: tuple.c:284
static GError * error
Definition: audctrl.c:30
#define TRUE
Definition: core.h:37
bool_t get_bool(const char *section, const char *name)
Definition: config.c:294
char * playlist_entry_get_filename(int playlist_num, int entry_num)
at
Definition: playlist-api.h:122
void str_unref(char *str)
Definition: strpool.c:89
EXPORT void index_free(Index *index)
Definition: index.c:52
EXPORT VFSFile * vfs_fopen(const char *path, const char *mode)
Opens a stream from a VFS transport using one of the registered VFSConstructor handlers.
Definition: vfs.c:122
EXPORT bool_t uri_get_extension(const char *uri, char *buf, int buflen)
Definition: audstrings.c:260
bool_t playlist_load(const char *filename, char **title, Index **filenames_p, Index **tuples_p)
void playlist_set_title(int playlist_num, const char *title)
Definition: playlist-new.c:810
Index Index tuples
Definition: playlist-api.h:122
void data PluginHandle plugin
Definition: plugins-api.h:54
void interface_show_error(const char *message)
Definition: interface.c:115
char ** filenames
Definition: main.c:56
bool_t(* save)(const char *path, VFSFile *file, const char *title, Index *filenames, Index *tuples)
Definition: plugin.h:158
#define SPRINTF(s,...)
Definition: core.h:46
bool_t playlist_save(int list, const char *filename)