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 }
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
char * str_printf(const char *format,...)
Definition: strpool.c:163
#define FALSE
Definition: core.h:37
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:29
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:39
bool_t get_bool(const char *section, const char *name)
Definition: config.c:300
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:131
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 playlist_save(int list, const char *filename)