aboutsummaryrefslogtreecommitdiff
path: root/src/playlist
diff options
context:
space:
mode:
Diffstat (limited to 'src/playlist')
-rw-r--r--src/playlist/AsxPlaylistPlugin.cxx (renamed from src/playlist/asx_playlist_plugin.c)126
-rw-r--r--src/playlist/AsxPlaylistPlugin.hxx (renamed from src/playlist/asx_playlist_plugin.h)6
-rw-r--r--src/playlist/CuePlaylistPlugin.cxx (renamed from src/playlist/cue_playlist_plugin.c)36
-rw-r--r--src/playlist/CuePlaylistPlugin.hxx (renamed from src/playlist/cue_playlist_plugin.h)6
-rw-r--r--src/playlist/DespotifyPlaylistPlugin.cxx146
-rw-r--r--src/playlist/DespotifyPlaylistPlugin.hxx (renamed from src/playlist/despotify_playlist_plugin.h)6
-rw-r--r--src/playlist/EmbeddedCuePlaylistPlugin.cxx (renamed from src/playlist/embcue_playlist_plugin.c)43
-rw-r--r--src/playlist/EmbeddedCuePlaylistPlugin.hxx (renamed from src/playlist/embcue_playlist_plugin.h)6
-rw-r--r--src/playlist/ExtM3uPlaylistPlugin.cxx (renamed from src/playlist/extm3u_playlist_plugin.c)45
-rw-r--r--src/playlist/ExtM3uPlaylistPlugin.hxx (renamed from src/playlist/extm3u_playlist_plugin.h)6
-rw-r--r--src/playlist/LastFMPlaylistPlugin.cxx (renamed from src/playlist/lastfm_playlist_plugin.c)43
-rw-r--r--src/playlist/LastFMPlaylistPlugin.hxx (renamed from src/playlist/lastfm_playlist_plugin.h)6
-rw-r--r--src/playlist/M3uPlaylistPlugin.cxx (renamed from src/playlist/m3u_playlist_plugin.c)36
-rw-r--r--src/playlist/M3uPlaylistPlugin.hxx (renamed from src/playlist/m3u_playlist_plugin.h)6
-rw-r--r--src/playlist/MemoryPlaylistProvider.cxx69
-rw-r--r--src/playlist/MemoryPlaylistProvider.hxx39
-rw-r--r--src/playlist/PlsPlaylistPlugin.cxx (renamed from src/playlist/pls_playlist_plugin.c)81
-rw-r--r--src/playlist/PlsPlaylistPlugin.hxx (renamed from src/playlist/pls_playlist_plugin.h)6
-rw-r--r--src/playlist/RssPlaylistPlugin.cxx (renamed from src/playlist/rss_playlist_plugin.c)125
-rw-r--r--src/playlist/RssPlaylistPlugin.hxx (renamed from src/playlist/rss_playlist_plugin.h)6
-rw-r--r--src/playlist/SoundCloudPlaylistPlugin.cxx (renamed from src/playlist/soundcloud_playlist_plugin.c)78
-rw-r--r--src/playlist/SoundCloudPlaylistPlugin.hxx (renamed from src/playlist/soundcloud_playlist_plugin.h)6
-rw-r--r--src/playlist/XspfPlaylistPlugin.cxx (renamed from src/playlist/xspf_playlist_plugin.c)156
-rw-r--r--src/playlist/XspfPlaylistPlugin.hxx (renamed from src/playlist/xspf_playlist_plugin.h)6
-rw-r--r--src/playlist/despotify_playlist_plugin.c217
25 files changed, 588 insertions, 718 deletions
diff --git a/src/playlist/asx_playlist_plugin.c b/src/playlist/AsxPlaylistPlugin.cxx
index 29868785..25319ca6 100644
--- a/src/playlist/asx_playlist_plugin.c
+++ b/src/playlist/AsxPlaylistPlugin.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -18,8 +18,8 @@
*/
#include "config.h"
-#include "playlist/asx_playlist_plugin.h"
-#include "playlist_plugin.h"
+#include "AsxPlaylistPlugin.hxx"
+#include "MemoryPlaylistProvider.hxx"
#include "input_stream.h"
#include "song.h"
#include "tag.h"
@@ -35,12 +35,12 @@
/**
* This is the state object for the GLib XML parser.
*/
-struct asx_parser {
+struct AsxParser {
/**
* The list of songs (in reverse order because that's faster
* while adding).
*/
- GSList *songs;
+ std::forward_list<SongPointer> songs;
/**
* The current position in the XML file.
@@ -61,6 +61,10 @@ struct asx_parser {
* element.
*/
struct song *song;
+
+ AsxParser()
+ :state(ROOT) {}
+
};
static const gchar *
@@ -81,19 +85,19 @@ asx_start_element(G_GNUC_UNUSED GMarkupParseContext *context,
const gchar **attribute_values,
gpointer user_data, G_GNUC_UNUSED GError **error)
{
- struct asx_parser *parser = user_data;
+ AsxParser *parser = (AsxParser *)user_data;
switch (parser->state) {
- case ROOT:
+ case AsxParser::ROOT:
if (g_ascii_strcasecmp(element_name, "entry") == 0) {
- parser->state = ENTRY;
+ parser->state = AsxParser::ENTRY;
parser->song = song_remote_new("asx:");
parser->tag = TAG_NUM_OF_ITEM_TYPES;
}
break;
- case ENTRY:
+ case AsxParser::ENTRY:
if (g_ascii_strcasecmp(element_name, "ref") == 0) {
const gchar *href = get_attribute(attribute_names,
attribute_values,
@@ -130,21 +134,20 @@ asx_end_element(G_GNUC_UNUSED GMarkupParseContext *context,
const gchar *element_name,
gpointer user_data, G_GNUC_UNUSED GError **error)
{
- struct asx_parser *parser = user_data;
+ AsxParser *parser = (AsxParser *)user_data;
switch (parser->state) {
- case ROOT:
+ case AsxParser::ROOT:
break;
- case ENTRY:
+ case AsxParser::ENTRY:
if (g_ascii_strcasecmp(element_name, "entry") == 0) {
if (strcmp(parser->song->uri, "asx:") != 0)
- parser->songs = g_slist_prepend(parser->songs,
- parser->song);
+ parser->songs.emplace_front(parser->song);
else
song_free(parser->song);
- parser->state = ROOT;
+ parser->state = AsxParser::ROOT;
} else
parser->tag = TAG_NUM_OF_ITEM_TYPES;
@@ -157,13 +160,13 @@ asx_text(G_GNUC_UNUSED GMarkupParseContext *context,
const gchar *text, gsize text_len,
gpointer user_data, G_GNUC_UNUSED GError **error)
{
- struct asx_parser *parser = user_data;
+ AsxParser *parser = (AsxParser *)user_data;
switch (parser->state) {
- case ROOT:
+ case AsxParser::ROOT:
break;
- case ENTRY:
+ case AsxParser::ENTRY:
if (parser->tag != TAG_NUM_OF_ITEM_TYPES) {
if (parser->song->tag == NULL)
parser->song->tag = tag_new();
@@ -176,29 +179,20 @@ asx_text(G_GNUC_UNUSED GMarkupParseContext *context,
}
static const GMarkupParser asx_parser = {
- .start_element = asx_start_element,
- .end_element = asx_end_element,
- .text = asx_text,
+ asx_start_element,
+ asx_end_element,
+ asx_text,
+ nullptr,
+ nullptr,
};
static void
-song_free_callback(gpointer data, G_GNUC_UNUSED gpointer user_data)
-{
- struct song *song = data;
-
- song_free(song);
-}
-
-static void
asx_parser_destroy(gpointer data)
{
- struct asx_parser *parser = data;
+ AsxParser *parser = (AsxParser *)data;
- if (parser->state >= ENTRY)
+ if (parser->state >= AsxParser::ENTRY)
song_free(parser->song);
-
- g_slist_foreach(parser->songs, song_free_callback, NULL);
- g_slist_free(parser->songs);
}
/*
@@ -206,20 +200,10 @@ asx_parser_destroy(gpointer data)
*
*/
-struct asx_playlist {
- struct playlist_provider base;
-
- GSList *songs;
-};
-
static struct playlist_provider *
asx_open_stream(struct input_stream *is)
{
- struct asx_parser parser = {
- .songs = NULL,
- .state = ROOT,
- };
- struct asx_playlist *playlist;
+ AsxParser parser;
GMarkupParseContext *context;
char buffer[1024];
size_t nbytes;
@@ -264,41 +248,13 @@ asx_open_stream(struct input_stream *is)
return NULL;
}
- /* create a #asx_playlist object from the parsed song list */
-
- playlist = g_new(struct asx_playlist, 1);
- playlist_provider_init(&playlist->base, &asx_playlist_plugin);
- playlist->songs = g_slist_reverse(parser.songs);
- parser.songs = NULL;
+ parser.songs.reverse();
+ MemoryPlaylistProvider *playlist =
+ new MemoryPlaylistProvider(std::move(parser.songs));
g_markup_parse_context_free(context);
- return &playlist->base;
-}
-
-static void
-asx_close(struct playlist_provider *_playlist)
-{
- struct asx_playlist *playlist = (struct asx_playlist *)_playlist;
-
- g_slist_foreach(playlist->songs, song_free_callback, NULL);
- g_slist_free(playlist->songs);
- g_free(playlist);
-}
-
-static struct song *
-asx_read(struct playlist_provider *_playlist)
-{
- struct asx_playlist *playlist = (struct asx_playlist *)_playlist;
- struct song *song;
-
- if (playlist->songs == NULL)
- return NULL;
-
- song = playlist->songs->data;
- playlist->songs = g_slist_remove(playlist->songs, song);
-
- return song;
+ return playlist;
}
static const char *const asx_suffixes[] = {
@@ -312,12 +268,16 @@ static const char *const asx_mime_types[] = {
};
const struct playlist_plugin asx_playlist_plugin = {
- .name = "asx",
+ "asx",
- .open_stream = asx_open_stream,
- .close = asx_close,
- .read = asx_read,
+ nullptr,
+ nullptr,
+ nullptr,
+ asx_open_stream,
+ nullptr,
+ nullptr,
- .suffixes = asx_suffixes,
- .mime_types = asx_mime_types,
+ nullptr,
+ asx_suffixes,
+ asx_mime_types,
};
diff --git a/src/playlist/asx_playlist_plugin.h b/src/playlist/AsxPlaylistPlugin.hxx
index 6c01c120..240c1824 100644
--- a/src/playlist/asx_playlist_plugin.h
+++ b/src/playlist/AsxPlaylistPlugin.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -17,8 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef MPD_PLAYLIST_ASX_PLAYLIST_PLUGIN_H
-#define MPD_PLAYLIST_ASX_PLAYLIST_PLUGIN_H
+#ifndef MPD_ASX_PLAYLIST_PLUGIN_HXX
+#define MPD_ASX_PLAYLIST_PLUGIN_HXX
extern const struct playlist_plugin asx_playlist_plugin;
diff --git a/src/playlist/cue_playlist_plugin.c b/src/playlist/CuePlaylistPlugin.cxx
index b85de77d..07eb5e24 100644
--- a/src/playlist/cue_playlist_plugin.c
+++ b/src/playlist/CuePlaylistPlugin.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -18,13 +18,16 @@
*/
#include "config.h"
-#include "playlist/cue_playlist_plugin.h"
-#include "playlist_plugin.h"
+#include "CuePlaylistPlugin.hxx"
+#include "PlaylistPlugin.hxx"
#include "tag.h"
#include "song.h"
-#include "cue/cue_parser.h"
#include "input_stream.h"
+
+extern "C" {
#include "text_input_stream.h"
+#include "cue/cue_parser.h"
+}
#include <glib.h>
#include <assert.h>
@@ -33,7 +36,7 @@
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "cue"
-struct cue_playlist {
+struct CuePlaylist {
struct playlist_provider base;
struct input_stream *is;
@@ -44,21 +47,20 @@ struct cue_playlist {
static struct playlist_provider *
cue_playlist_open_stream(struct input_stream *is)
{
- struct cue_playlist *playlist = g_new(struct cue_playlist, 1);
+ CuePlaylist *playlist = g_new(CuePlaylist, 1);
playlist_provider_init(&playlist->base, &cue_playlist_plugin);
playlist->is = is;
playlist->tis = text_input_stream_new(is);
playlist->parser = cue_parser_new();
-
return &playlist->base;
}
static void
cue_playlist_close(struct playlist_provider *_playlist)
{
- struct cue_playlist *playlist = (struct cue_playlist *)_playlist;
+ CuePlaylist *playlist = (CuePlaylist *)_playlist;
cue_parser_free(playlist->parser);
text_input_stream_free(playlist->tis);
@@ -68,7 +70,7 @@ cue_playlist_close(struct playlist_provider *_playlist)
static struct song *
cue_playlist_read(struct playlist_provider *_playlist)
{
- struct cue_playlist *playlist = (struct cue_playlist *)_playlist;
+ CuePlaylist *playlist = (CuePlaylist *)_playlist;
struct song *song = cue_parser_get(playlist->parser);
if (song != NULL)
@@ -97,12 +99,16 @@ static const char *const cue_playlist_mime_types[] = {
};
const struct playlist_plugin cue_playlist_plugin = {
- .name = "cue",
+ "cue",
- .open_stream = cue_playlist_open_stream,
- .close = cue_playlist_close,
- .read = cue_playlist_read,
+ nullptr,
+ nullptr,
+ nullptr,
+ cue_playlist_open_stream,
+ cue_playlist_close,
+ cue_playlist_read,
- .suffixes = cue_playlist_suffixes,
- .mime_types = cue_playlist_mime_types,
+ nullptr,
+ cue_playlist_suffixes,
+ cue_playlist_mime_types,
};
diff --git a/src/playlist/cue_playlist_plugin.h b/src/playlist/CuePlaylistPlugin.hxx
index c02e2235..cf5e3a8f 100644
--- a/src/playlist/cue_playlist_plugin.h
+++ b/src/playlist/CuePlaylistPlugin.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -17,8 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef MPD_PLAYLIST_CUE_PLAYLIST_PLUGIN_H
-#define MPD_PLAYLIST_CUE_PLAYLIST_PLUGIN_H
+#ifndef MPD_CUE_PLAYLIST_PLUGIN_HXX
+#define MPD_CUE_PLAYLIST_PLUGIN_HXX
extern const struct playlist_plugin cue_playlist_plugin;
diff --git a/src/playlist/DespotifyPlaylistPlugin.cxx b/src/playlist/DespotifyPlaylistPlugin.cxx
new file mode 100644
index 00000000..25f12785
--- /dev/null
+++ b/src/playlist/DespotifyPlaylistPlugin.cxx
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2011-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+#include "DespotifyPlaylistPlugin.hxx"
+#include "DespotifyUtils.hxx"
+#include "MemoryPlaylistProvider.hxx"
+#include "tag.h"
+#include "song.h"
+
+extern "C" {
+#include <despotify.h>
+}
+
+#include <glib.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+static void
+add_song(std::forward_list<SongPointer> &songs, struct ds_track *track)
+{
+ const char *dsp_scheme = despotify_playlist_plugin.schemes[0];
+ struct song *song;
+ char uri[128];
+ char *ds_uri;
+
+ /* Create a spt://... URI for MPD */
+ g_snprintf(uri, sizeof(uri), "%s://", dsp_scheme);
+ ds_uri = uri + strlen(dsp_scheme) + 3;
+
+ if (despotify_track_to_uri(track, ds_uri) != ds_uri) {
+ /* Should never really fail, but let's be sure */
+ g_debug("Can't add track %s\n", track->title);
+ return;
+ }
+
+ song = song_remote_new(uri);
+ song->tag = mpd_despotify_tag_from_track(track);
+
+ songs.emplace_front(song);
+}
+
+static bool
+parse_track(struct despotify_session *session,
+ std::forward_list<SongPointer> &songs,
+ struct ds_link *link)
+{
+ struct ds_track *track = despotify_link_get_track(session, link);
+ if (track == nullptr)
+ return false;
+
+ add_song(songs, track);
+ return true;
+}
+
+static bool
+parse_playlist(struct despotify_session *session,
+ std::forward_list<SongPointer> &songs,
+ struct ds_link *link)
+{
+ ds_playlist *playlist = despotify_link_get_playlist(session, link);
+ if (playlist == nullptr)
+ return false;
+
+ for (ds_track *track = playlist->tracks; track != nullptr;
+ track = track->next)
+ add_song(songs, track);
+
+ return true;
+}
+
+static struct playlist_provider *
+despotify_playlist_open_uri(const char *url,
+ gcc_unused Mutex &mutex, gcc_unused Cond &cond)
+{
+ despotify_session *session = mpd_despotify_get_session();
+ if (session == nullptr)
+ return nullptr;
+
+ /* Get link without spt:// */
+ ds_link *link =
+ despotify_link_from_uri(url + strlen(despotify_playlist_plugin.schemes[0]) + 3);
+ if (link == nullptr) {
+ g_debug("Can't find %s\n", url);
+ return nullptr;
+ }
+
+ std::forward_list<SongPointer> songs;
+
+ bool parse_result;
+ switch (link->type) {
+ case LINK_TYPE_TRACK:
+ parse_result = parse_track(session, songs, link);
+ break;
+ case LINK_TYPE_PLAYLIST:
+ parse_result = parse_playlist(session, songs, link);
+ break;
+ default:
+ parse_result = false;
+ break;
+ }
+
+ despotify_free_link(link);
+ if (!parse_result)
+ return nullptr;
+
+ songs.reverse();
+ return new MemoryPlaylistProvider(std::move(songs));
+}
+
+static const char *const despotify_schemes[] = {
+ "spt",
+ nullptr
+};
+
+const struct playlist_plugin despotify_playlist_plugin = {
+ "despotify",
+
+ nullptr,
+ nullptr,
+ despotify_playlist_open_uri,
+ nullptr,
+ nullptr,
+ nullptr,
+
+ despotify_schemes,
+ nullptr,
+ nullptr,
+};
diff --git a/src/playlist/despotify_playlist_plugin.h b/src/playlist/DespotifyPlaylistPlugin.hxx
index f8ee20de..c1e5b7f3 100644
--- a/src/playlist/despotify_playlist_plugin.h
+++ b/src/playlist/DespotifyPlaylistPlugin.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Music Player Daemon Project
+ * Copyright (C) 2011-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -17,8 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef MPD_PLAYLIST_DESPOTIFY_PLAYLIST_PLUGIN_H
-#define MPD_PLAYLIST_DESPOTIFY_PLAYLIST_PLUGIN_H
+#ifndef MPD_PLAYLIST_DESPOTIFY_PLAYLIST_PLUGIN_HXX
+#define MPD_PLAYLIST_DESPOTIFY_PLAYLIST_PLUGIN_HXX
extern const struct playlist_plugin despotify_playlist_plugin;
diff --git a/src/playlist/embcue_playlist_plugin.c b/src/playlist/EmbeddedCuePlaylistPlugin.cxx
index 6d9a957f..04cb12ec 100644
--- a/src/playlist/embcue_playlist_plugin.c
+++ b/src/playlist/EmbeddedCuePlaylistPlugin.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2012 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -24,15 +24,18 @@
*/
#include "config.h"
-#include "playlist/embcue_playlist_plugin.h"
-#include "playlist_plugin.h"
+#include "EmbeddedCuePlaylistPlugin.hxx"
+#include "PlaylistPlugin.hxx"
#include "tag.h"
#include "tag_handler.h"
-#include "tag_file.h"
+#include "song.h"
+#include "TagFile.hxx"
+
+extern "C" {
#include "tag_ape.h"
#include "tag_id3.h"
-#include "song.h"
#include "cue/cue_parser.h"
+}
#include <glib.h>
#include <assert.h>
@@ -67,7 +70,7 @@ struct embcue_playlist {
static void
embcue_tag_pair(const char *name, const char *value, void *ctx)
{
- struct embcue_playlist *playlist = ctx;
+ struct embcue_playlist *playlist = (struct embcue_playlist *)ctx;
if (playlist->cuesheet == NULL &&
g_ascii_strcasecmp(name, "cuesheet") == 0)
@@ -75,13 +78,15 @@ embcue_tag_pair(const char *name, const char *value, void *ctx)
}
static const struct tag_handler embcue_tag_handler = {
- .pair = embcue_tag_pair,
+ nullptr,
+ nullptr,
+ embcue_tag_pair,
};
static struct playlist_provider *
embcue_playlist_open_uri(const char *uri,
- G_GNUC_UNUSED GMutex *mutex,
- G_GNUC_UNUSED GCond *cond)
+ gcc_unused Mutex &mutex,
+ gcc_unused Cond &cond)
{
if (!g_path_is_absolute(uri))
/* only local files supported */
@@ -170,12 +175,16 @@ static const char *const embcue_playlist_suffixes[] = {
};
const struct playlist_plugin embcue_playlist_plugin = {
- .name = "cue",
-
- .open_uri = embcue_playlist_open_uri,
- .close = embcue_playlist_close,
- .read = embcue_playlist_read,
-
- .suffixes = embcue_playlist_suffixes,
- .mime_types = NULL,
+ "cue",
+
+ nullptr,
+ nullptr,
+ embcue_playlist_open_uri,
+ nullptr,
+ embcue_playlist_close,
+ embcue_playlist_read,
+
+ embcue_playlist_suffixes,
+ nullptr,
+ nullptr,
};
diff --git a/src/playlist/embcue_playlist_plugin.h b/src/playlist/EmbeddedCuePlaylistPlugin.hxx
index c5f21b27..e306730f 100644
--- a/src/playlist/embcue_playlist_plugin.h
+++ b/src/playlist/EmbeddedCuePlaylistPlugin.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2012 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -17,8 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef MPD_PLAYLIST_EMBCUE_PLAYLIST_PLUGIN_H
-#define MPD_PLAYLIST_EMBCUE_PLAYLIST_PLUGIN_H
+#ifndef MPD_EMBCUE_PLAYLIST_PLUGIN_HXX
+#define MPD_EMBCUE_PLAYLIST_PLUGIN_HXX
extern const struct playlist_plugin embcue_playlist_plugin;
diff --git a/src/playlist/extm3u_playlist_plugin.c b/src/playlist/ExtM3uPlaylistPlugin.cxx
index 19be8d1c..ce026dab 100644
--- a/src/playlist/extm3u_playlist_plugin.c
+++ b/src/playlist/ExtM3uPlaylistPlugin.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -18,20 +18,22 @@
*/
#include "config.h"
-#include "playlist/extm3u_playlist_plugin.h"
-#include "playlist_plugin.h"
-#include "text_input_stream.h"
-#include "uri.h"
+#include "ExtM3uPlaylistPlugin.hxx"
+#include "PlaylistPlugin.hxx"
#include "song.h"
#include "tag.h"
#include "string_util.h"
+extern "C" {
+#include "text_input_stream.h"
+}
+
#include <glib.h>
#include <string.h>
#include <stdlib.h>
-struct extm3u_playlist {
+struct ExtM3uPlaylist {
struct playlist_provider base;
struct text_input_stream *tis;
@@ -40,13 +42,10 @@ struct extm3u_playlist {
static struct playlist_provider *
extm3u_open_stream(struct input_stream *is)
{
- struct extm3u_playlist *playlist;
- const char *line;
-
- playlist = g_new(struct extm3u_playlist, 1);
+ ExtM3uPlaylist *playlist = g_new(ExtM3uPlaylist, 1);
playlist->tis = text_input_stream_new(is);
- line = text_input_stream_read(playlist->tis);
+ const char *line = text_input_stream_read(playlist->tis);
if (line == NULL || strcmp(line, "#EXTM3U") != 0) {
/* no EXTM3U header: fall back to the plain m3u
plugin */
@@ -62,7 +61,7 @@ extm3u_open_stream(struct input_stream *is)
static void
extm3u_close(struct playlist_provider *_playlist)
{
- struct extm3u_playlist *playlist = (struct extm3u_playlist *)_playlist;
+ ExtM3uPlaylist *playlist = (ExtM3uPlaylist *)_playlist;
text_input_stream_free(playlist->tis);
g_free(playlist);
@@ -111,7 +110,7 @@ extm3u_parse_tag(const char *line)
static struct song *
extm3u_read(struct playlist_provider *_playlist)
{
- struct extm3u_playlist *playlist = (struct extm3u_playlist *)_playlist;
+ ExtM3uPlaylist *playlist = (ExtM3uPlaylist *)_playlist;
struct tag *tag = NULL;
const char *line;
struct song *song;
@@ -151,12 +150,16 @@ static const char *const extm3u_mime_types[] = {
};
const struct playlist_plugin extm3u_playlist_plugin = {
- .name = "extm3u",
-
- .open_stream = extm3u_open_stream,
- .close = extm3u_close,
- .read = extm3u_read,
-
- .suffixes = extm3u_suffixes,
- .mime_types = extm3u_mime_types,
+ "extm3u",
+
+ nullptr,
+ nullptr,
+ nullptr,
+ extm3u_open_stream,
+ extm3u_close,
+ extm3u_read,
+
+ nullptr,
+ extm3u_suffixes,
+ extm3u_mime_types,
};
diff --git a/src/playlist/extm3u_playlist_plugin.h b/src/playlist/ExtM3uPlaylistPlugin.hxx
index 5f611ac9..844fba15 100644
--- a/src/playlist/extm3u_playlist_plugin.h
+++ b/src/playlist/ExtM3uPlaylistPlugin.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -17,8 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef MPD_PLAYLIST_EXTM3U_PLAYLIST_PLUGIN_H
-#define MPD_PLAYLIST_EXTM3U_PLAYLIST_PLUGIN_H
+#ifndef MPD_EXTM3U_PLAYLIST_PLUGIN_HXX
+#define MPD_EXTM3U_PLAYLIST_PLUGIN_HXX
extern const struct playlist_plugin extm3u_playlist_plugin;
diff --git a/src/playlist/lastfm_playlist_plugin.c b/src/playlist/LastFMPlaylistPlugin.cxx
index ead14dea..49638840 100644
--- a/src/playlist/lastfm_playlist_plugin.c
+++ b/src/playlist/LastFMPlaylistPlugin.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -18,11 +18,10 @@
*/
#include "config.h"
-#include "playlist/lastfm_playlist_plugin.h"
-#include "playlist_plugin.h"
-#include "playlist_list.h"
+#include "LastFMPlaylistPlugin.hxx"
+#include "PlaylistPlugin.hxx"
+#include "PlaylistRegistry.hxx"
#include "conf.h"
-#include "uri.h"
#include "song.h"
#include "input_stream.h"
@@ -80,7 +79,7 @@ lastfm_finish(void)
* @return data fetched, or NULL on error. Must be freed with g_free.
*/
static char *
-lastfm_get(const char *url, GMutex *mutex, GCond *cond)
+lastfm_get(const char *url, Mutex &mutex, Cond &cond)
{
struct input_stream *input_stream;
GError *error = NULL;
@@ -97,7 +96,7 @@ lastfm_get(const char *url, GMutex *mutex, GCond *cond)
return NULL;
}
- g_mutex_lock(mutex);
+ mutex.lock();
input_stream_wait_ready(input_stream);
@@ -114,7 +113,7 @@ lastfm_get(const char *url, GMutex *mutex, GCond *cond)
break;
/* I/O error */
- g_mutex_unlock(mutex);
+ mutex.unlock();
input_stream_close(input_stream);
return NULL;
}
@@ -122,7 +121,7 @@ lastfm_get(const char *url, GMutex *mutex, GCond *cond)
length += nbytes;
} while (length < sizeof(buffer));
- g_mutex_unlock(mutex);
+ mutex.unlock();
input_stream_close(input_stream);
return g_strndup(buffer, length);
@@ -155,7 +154,7 @@ lastfm_find(const char *response, const char *name)
}
static struct playlist_provider *
-lastfm_open_uri(const char *uri, GMutex *mutex, GCond *cond)
+lastfm_open_uri(const char *uri, Mutex &mutex, Cond &cond)
{
struct lastfm_playlist *playlist;
GError *error = NULL;
@@ -236,16 +235,15 @@ lastfm_open_uri(const char *uri, GMutex *mutex, GCond *cond)
return NULL;
}
- g_mutex_lock(mutex);
+ mutex.lock();
input_stream_wait_ready(playlist->is);
/* last.fm does not send a MIME type, we have to fake it here
:-( */
- g_free(playlist->is->mime);
- playlist->is->mime = g_strdup("application/xspf+xml");
+ input_stream_override_mime_type(playlist->is, "application/xspf+xml");
- g_mutex_unlock(mutex);
+ mutex.unlock();
/* parse the XSPF playlist */
@@ -284,13 +282,16 @@ static const char *const lastfm_schemes[] = {
};
const struct playlist_plugin lastfm_playlist_plugin = {
- .name = "lastfm",
+ "lastfm",
- .init = lastfm_init,
- .finish = lastfm_finish,
- .open_uri = lastfm_open_uri,
- .close = lastfm_close,
- .read = lastfm_read,
+ lastfm_init,
+ lastfm_finish,
+ lastfm_open_uri,
+ nullptr,
+ lastfm_close,
+ lastfm_read,
- .schemes = lastfm_schemes,
+ lastfm_schemes,
+ nullptr,
+ nullptr,
};
diff --git a/src/playlist/lastfm_playlist_plugin.h b/src/playlist/LastFMPlaylistPlugin.hxx
index 46a8b0ca..fe0e206d 100644
--- a/src/playlist/lastfm_playlist_plugin.h
+++ b/src/playlist/LastFMPlaylistPlugin.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -17,8 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef MPD_PLAYLIST_LASTFM_PLAYLIST_PLUGIN_H
-#define MPD_PLAYLIST_LASTFM_PLAYLIST_PLUGIN_H
+#ifndef MPD_LASTFM_PLAYLIST_PLUGIN_HXX
+#define MPD_LASTFM_PLAYLIST_PLUGIN_HXX
extern const struct playlist_plugin lastfm_playlist_plugin;
diff --git a/src/playlist/m3u_playlist_plugin.c b/src/playlist/M3uPlaylistPlugin.cxx
index 45b70d2b..eeecd277 100644
--- a/src/playlist/m3u_playlist_plugin.c
+++ b/src/playlist/M3uPlaylistPlugin.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -18,15 +18,17 @@
*/
#include "config.h"
-#include "playlist/m3u_playlist_plugin.h"
-#include "playlist_plugin.h"
-#include "text_input_stream.h"
-#include "uri.h"
+#include "M3uPlaylistPlugin.hxx"
+#include "PlaylistPlugin.hxx"
#include "song.h"
+extern "C" {
+#include "text_input_stream.h"
+}
+
#include <glib.h>
-struct m3u_playlist {
+struct M3uPlaylist {
struct playlist_provider base;
struct text_input_stream *tis;
@@ -35,7 +37,7 @@ struct m3u_playlist {
static struct playlist_provider *
m3u_open_stream(struct input_stream *is)
{
- struct m3u_playlist *playlist = g_new(struct m3u_playlist, 1);
+ M3uPlaylist *playlist = g_new(M3uPlaylist, 1);
playlist_provider_init(&playlist->base, &m3u_playlist_plugin);
playlist->tis = text_input_stream_new(is);
@@ -46,7 +48,7 @@ m3u_open_stream(struct input_stream *is)
static void
m3u_close(struct playlist_provider *_playlist)
{
- struct m3u_playlist *playlist = (struct m3u_playlist *)_playlist;
+ M3uPlaylist *playlist = (M3uPlaylist *)_playlist;
text_input_stream_free(playlist->tis);
g_free(playlist);
@@ -55,7 +57,7 @@ m3u_close(struct playlist_provider *_playlist)
static struct song *
m3u_read(struct playlist_provider *_playlist)
{
- struct m3u_playlist *playlist = (struct m3u_playlist *)_playlist;
+ M3uPlaylist *playlist = (M3uPlaylist *)_playlist;
const char *line;
do {
@@ -81,12 +83,16 @@ static const char *const m3u_mime_types[] = {
};
const struct playlist_plugin m3u_playlist_plugin = {
- .name = "m3u",
+ "m3u",
- .open_stream = m3u_open_stream,
- .close = m3u_close,
- .read = m3u_read,
+ nullptr,
+ nullptr,
+ nullptr,
+ m3u_open_stream,
+ m3u_close,
+ m3u_read,
- .suffixes = m3u_suffixes,
- .mime_types = m3u_mime_types,
+ nullptr,
+ m3u_suffixes,
+ m3u_mime_types,
};
diff --git a/src/playlist/m3u_playlist_plugin.h b/src/playlist/M3uPlaylistPlugin.hxx
index 3890a5fc..a2058bb2 100644
--- a/src/playlist/m3u_playlist_plugin.h
+++ b/src/playlist/M3uPlaylistPlugin.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -17,8 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef MPD_PLAYLIST_M3U_PLAYLIST_PLUGIN_H
-#define MPD_PLAYLIST_M3U_PLAYLIST_PLUGIN_H
+#ifndef MPD_M3U_PLAYLIST_PLUGIN_HXX
+#define MPD_M3U_PLAYLIST_PLUGIN_HXX
extern const struct playlist_plugin m3u_playlist_plugin;
diff --git a/src/playlist/MemoryPlaylistProvider.cxx b/src/playlist/MemoryPlaylistProvider.cxx
new file mode 100644
index 00000000..4fe3d6ce
--- /dev/null
+++ b/src/playlist/MemoryPlaylistProvider.cxx
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+#include "MemoryPlaylistProvider.hxx"
+#include "song.h"
+
+static void
+memory_playlist_close(struct playlist_provider *_playlist)
+{
+ MemoryPlaylistProvider *playlist = (MemoryPlaylistProvider *)_playlist;
+
+ delete playlist;
+}
+
+static struct song *
+memory_playlist_read(struct playlist_provider *_playlist)
+{
+ MemoryPlaylistProvider *playlist = (MemoryPlaylistProvider *)_playlist;
+
+ return playlist->Read();
+}
+
+static constexpr struct playlist_plugin memory_playlist_plugin = {
+ nullptr,
+
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ memory_playlist_close,
+ memory_playlist_read,
+
+ nullptr,
+ nullptr,
+ nullptr,
+};
+
+MemoryPlaylistProvider::MemoryPlaylistProvider(std::forward_list<SongPointer> &&_songs)
+ :songs(std::move(_songs)) {
+ playlist_provider_init(this, &memory_playlist_plugin);
+}
+
+inline song *
+MemoryPlaylistProvider::Read()
+{
+ if (songs.empty())
+ return NULL;
+
+ auto result = songs.front().Steal();
+ songs.pop_front();
+ return result;
+}
diff --git a/src/playlist/MemoryPlaylistProvider.hxx b/src/playlist/MemoryPlaylistProvider.hxx
new file mode 100644
index 00000000..246ffd10
--- /dev/null
+++ b/src/playlist/MemoryPlaylistProvider.hxx
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_MEMORY_PLAYLIST_PROVIDER_HXX
+#define MPD_MEMORY_PLAYLIST_PROVIDER_HXX
+
+#include "PlaylistPlugin.hxx"
+#include "SongPointer.hxx"
+
+#include <forward_list>
+
+struct song;
+
+class MemoryPlaylistProvider : public playlist_provider {
+ std::forward_list<SongPointer> songs;
+
+public:
+ MemoryPlaylistProvider(std::forward_list<SongPointer> &&_songs);
+
+ song *Read();
+};
+
+#endif
diff --git a/src/playlist/pls_playlist_plugin.c b/src/playlist/PlsPlaylistPlugin.cxx
index c4e5492a..3cf5f46e 100644
--- a/src/playlist/pls_playlist_plugin.c
+++ b/src/playlist/PlsPlaylistPlugin.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -18,21 +18,17 @@
*/
#include "config.h"
-#include "playlist/pls_playlist_plugin.h"
-#include "playlist_plugin.h"
+#include "PlsPlaylistPlugin.hxx"
+#include "MemoryPlaylistProvider.hxx"
#include "input_stream.h"
#include "uri.h"
#include "song.h"
#include "tag.h"
-#include <glib.h>
-
-struct pls_playlist {
- struct playlist_provider base;
- GSList *songs;
-};
+#include <glib.h>
-static void pls_parser(GKeyFile *keyfile, struct pls_playlist *playlist)
+static void
+pls_parser(GKeyFile *keyfile, std::forward_list<SongPointer> &songs)
{
gchar *key;
gchar *value;
@@ -97,7 +93,7 @@ static void pls_parser(GKeyFile *keyfile, struct pls_playlist *playlist)
if(error) g_error_free(error);
error = NULL;
- playlist->songs = g_slist_prepend(playlist->songs, song);
+ songs.emplace_front(song);
num_entries--;
}
@@ -111,7 +107,6 @@ pls_open_stream(struct input_stream *is)
char buffer[1024];
bool success;
GKeyFile *keyfile;
- struct pls_playlist *playlist;
GString *kf_data = g_string_new("");
do {
@@ -152,50 +147,12 @@ pls_open_stream(struct input_stream *is)
return NULL;
}
- playlist = g_new(struct pls_playlist, 1);
- playlist_provider_init(&playlist->base, &pls_playlist_plugin);
- playlist->songs = NULL;
-
- pls_parser(keyfile, playlist);
-
+ std::forward_list<SongPointer> songs;
+ pls_parser(keyfile, songs);
g_key_file_free(keyfile);
- return &playlist->base;
-}
-
-static void
-song_free_callback(gpointer data, G_GNUC_UNUSED gpointer user_data)
-{
- struct song *song = data;
-
- song_free(song);
-}
-
-static void
-pls_close(struct playlist_provider *_playlist)
-{
- struct pls_playlist *playlist = (struct pls_playlist *)_playlist;
-
- g_slist_foreach(playlist->songs, song_free_callback, NULL);
- g_slist_free(playlist->songs);
-
- g_free(playlist);
-
-}
-
-static struct song *
-pls_read(struct playlist_provider *_playlist)
-{
- struct pls_playlist *playlist = (struct pls_playlist *)_playlist;
- struct song *song;
-
- if (playlist->songs == NULL)
- return NULL;
-
- song = playlist->songs->data;
- playlist->songs = g_slist_remove(playlist->songs, song);
-
- return song;
+ songs.reverse();
+ return new MemoryPlaylistProvider(std::move(songs));
}
static const char *const pls_suffixes[] = {
@@ -209,12 +166,16 @@ static const char *const pls_mime_types[] = {
};
const struct playlist_plugin pls_playlist_plugin = {
- .name = "pls",
+ "pls",
- .open_stream = pls_open_stream,
- .close = pls_close,
- .read = pls_read,
+ nullptr,
+ nullptr,
+ nullptr,
+ pls_open_stream,
+ nullptr,
+ nullptr,
- .suffixes = pls_suffixes,
- .mime_types = pls_mime_types,
+ nullptr,
+ pls_suffixes,
+ pls_mime_types,
};
diff --git a/src/playlist/pls_playlist_plugin.h b/src/playlist/PlsPlaylistPlugin.hxx
index d03435f6..3fafd36d 100644
--- a/src/playlist/pls_playlist_plugin.h
+++ b/src/playlist/PlsPlaylistPlugin.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -17,8 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef MPD_PLAYLIST_PLS_PLAYLIST_PLUGIN_H
-#define MPD_PLAYLIST_PLS_PLAYLIST_PLUGIN_H
+#ifndef MPD_PLS_PLAYLIST_PLUGIN_HXX
+#define MPD_PLS_PLAYLIST_PLUGIN_HXX
extern const struct playlist_plugin pls_playlist_plugin;
diff --git a/src/playlist/rss_playlist_plugin.c b/src/playlist/RssPlaylistPlugin.cxx
index 6740cba7..3b69202e 100644
--- a/src/playlist/rss_playlist_plugin.c
+++ b/src/playlist/RssPlaylistPlugin.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -18,8 +18,8 @@
*/
#include "config.h"
-#include "playlist/rss_playlist_plugin.h"
-#include "playlist_plugin.h"
+#include "RssPlaylistPlugin.hxx"
+#include "MemoryPlaylistProvider.hxx"
#include "input_stream.h"
#include "song.h"
#include "tag.h"
@@ -35,12 +35,12 @@
/**
* This is the state object for the GLib XML parser.
*/
-struct rss_parser {
+struct RssParser {
/**
* The list of songs (in reverse order because that's faster
* while adding).
*/
- GSList *songs;
+ std::forward_list<SongPointer> songs;
/**
* The current position in the XML file.
@@ -61,6 +61,9 @@ struct rss_parser {
* element.
*/
struct song *song;
+
+ RssParser()
+ :state(ROOT) {}
};
static const gchar *
@@ -81,19 +84,19 @@ rss_start_element(G_GNUC_UNUSED GMarkupParseContext *context,
const gchar **attribute_values,
gpointer user_data, G_GNUC_UNUSED GError **error)
{
- struct rss_parser *parser = user_data;
+ RssParser *parser = (RssParser *)user_data;
switch (parser->state) {
- case ROOT:
+ case RssParser::ROOT:
if (g_ascii_strcasecmp(element_name, "item") == 0) {
- parser->state = ITEM;
+ parser->state = RssParser::ITEM;
parser->song = song_remote_new("rss:");
parser->tag = TAG_NUM_OF_ITEM_TYPES;
}
break;
- case ITEM:
+ case RssParser::ITEM:
if (g_ascii_strcasecmp(element_name, "enclosure") == 0) {
const gchar *href = get_attribute(attribute_names,
attribute_values,
@@ -128,21 +131,20 @@ rss_end_element(G_GNUC_UNUSED GMarkupParseContext *context,
const gchar *element_name,
gpointer user_data, G_GNUC_UNUSED GError **error)
{
- struct rss_parser *parser = user_data;
+ RssParser *parser = (RssParser *)user_data;
switch (parser->state) {
- case ROOT:
+ case RssParser::ROOT:
break;
- case ITEM:
+ case RssParser::ITEM:
if (g_ascii_strcasecmp(element_name, "item") == 0) {
if (strcmp(parser->song->uri, "rss:") != 0)
- parser->songs = g_slist_prepend(parser->songs,
- parser->song);
+ parser->songs.emplace_front(parser->song);
else
song_free(parser->song);
- parser->state = ROOT;
+ parser->state = RssParser::ROOT;
} else
parser->tag = TAG_NUM_OF_ITEM_TYPES;
@@ -155,13 +157,13 @@ rss_text(G_GNUC_UNUSED GMarkupParseContext *context,
const gchar *text, gsize text_len,
gpointer user_data, G_GNUC_UNUSED GError **error)
{
- struct rss_parser *parser = user_data;
+ RssParser *parser = (RssParser *)user_data;
switch (parser->state) {
- case ROOT:
+ case RssParser::ROOT:
break;
- case ITEM:
+ case RssParser::ITEM:
if (parser->tag != TAG_NUM_OF_ITEM_TYPES) {
if (parser->song->tag == NULL)
parser->song->tag = tag_new();
@@ -174,29 +176,20 @@ rss_text(G_GNUC_UNUSED GMarkupParseContext *context,
}
static const GMarkupParser rss_parser = {
- .start_element = rss_start_element,
- .end_element = rss_end_element,
- .text = rss_text,
+ rss_start_element,
+ rss_end_element,
+ rss_text,
+ nullptr,
+ nullptr,
};
static void
-song_free_callback(gpointer data, G_GNUC_UNUSED gpointer user_data)
-{
- struct song *song = data;
-
- song_free(song);
-}
-
-static void
rss_parser_destroy(gpointer data)
{
- struct rss_parser *parser = data;
+ RssParser *parser = (RssParser *)data;
- if (parser->state >= ITEM)
+ if (parser->state >= RssParser::ITEM)
song_free(parser->song);
-
- g_slist_foreach(parser->songs, song_free_callback, NULL);
- g_slist_free(parser->songs);
}
/*
@@ -204,20 +197,10 @@ rss_parser_destroy(gpointer data)
*
*/
-struct rss_playlist {
- struct playlist_provider base;
-
- GSList *songs;
-};
-
static struct playlist_provider *
rss_open_stream(struct input_stream *is)
{
- struct rss_parser parser = {
- .songs = NULL,
- .state = ROOT,
- };
- struct rss_playlist *playlist;
+ RssParser parser;
GMarkupParseContext *context;
char buffer[1024];
size_t nbytes;
@@ -262,41 +245,13 @@ rss_open_stream(struct input_stream *is)
return NULL;
}
- /* create a #rss_playlist object from the parsed song list */
-
- playlist = g_new(struct rss_playlist, 1);
- playlist_provider_init(&playlist->base, &rss_playlist_plugin);
- playlist->songs = g_slist_reverse(parser.songs);
- parser.songs = NULL;
+ parser.songs.reverse();
+ MemoryPlaylistProvider *playlist =
+ new MemoryPlaylistProvider(std::move(parser.songs));
g_markup_parse_context_free(context);
- return &playlist->base;
-}
-
-static void
-rss_close(struct playlist_provider *_playlist)
-{
- struct rss_playlist *playlist = (struct rss_playlist *)_playlist;
-
- g_slist_foreach(playlist->songs, song_free_callback, NULL);
- g_slist_free(playlist->songs);
- g_free(playlist);
-}
-
-static struct song *
-rss_read(struct playlist_provider *_playlist)
-{
- struct rss_playlist *playlist = (struct rss_playlist *)_playlist;
- struct song *song;
-
- if (playlist->songs == NULL)
- return NULL;
-
- song = playlist->songs->data;
- playlist->songs = g_slist_remove(playlist->songs, song);
-
- return song;
+ return playlist;
}
static const char *const rss_suffixes[] = {
@@ -311,12 +266,16 @@ static const char *const rss_mime_types[] = {
};
const struct playlist_plugin rss_playlist_plugin = {
- .name = "rss",
+ "rss",
- .open_stream = rss_open_stream,
- .close = rss_close,
- .read = rss_read,
+ nullptr,
+ nullptr,
+ nullptr,
+ rss_open_stream,
+ nullptr,
+ nullptr,
- .suffixes = rss_suffixes,
- .mime_types = rss_mime_types,
+ nullptr,
+ rss_suffixes,
+ rss_mime_types,
};
diff --git a/src/playlist/rss_playlist_plugin.h b/src/playlist/RssPlaylistPlugin.hxx
index 3b376de7..f49f7e9c 100644
--- a/src/playlist/rss_playlist_plugin.h
+++ b/src/playlist/RssPlaylistPlugin.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -17,8 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef MPD_PLAYLIST_RSS_PLAYLIST_PLUGIN_H
-#define MPD_PLAYLIST_RSS_PLAYLIST_PLUGIN_H
+#ifndef MPD_RSS_PLAYLIST_PLUGIN_HXX
+#define MPD_RSS_PLAYLIST_PLUGIN_HXX
extern const struct playlist_plugin rss_playlist_plugin;
diff --git a/src/playlist/soundcloud_playlist_plugin.c b/src/playlist/SoundCloudPlaylistPlugin.cxx
index 7c79f880..5a258865 100644
--- a/src/playlist/soundcloud_playlist_plugin.c
+++ b/src/playlist/SoundCloudPlaylistPlugin.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -18,10 +18,10 @@
*/
#include "config.h"
-#include "playlist/soundcloud_playlist_plugin.h"
+#include "SoundCloudPlaylistPlugin.hxx"
+#include "MemoryPlaylistProvider.hxx"
#include "conf.h"
#include "input_stream.h"
-#include "playlist_plugin.h"
#include "song.h"
#include "tag.h"
@@ -30,12 +30,6 @@
#include <string.h>
-struct soundcloud_playlist {
- struct playlist_provider base;
-
- GSList *songs;
-};
-
static struct {
char *apikey;
} soundcloud_config;
@@ -107,7 +101,8 @@ struct parse_data {
long duration;
char* title;
int got_url; /* nesting level of last stream_url */
- GSList* songs;
+
+ std::forward_list<SongPointer> songs;
};
static int handle_integer(void *ctx,
@@ -221,7 +216,7 @@ static int handle_end_map(void *ctx)
tag_add_item(t, TAG_NAME, data->title);
s->tag = t;
- data->songs = g_slist_prepend(data->songs, s);
+ data->songs.emplace_front(s);
return 1;
}
@@ -247,7 +242,8 @@ static yajl_callbacks parse_callbacks = {
* @return -1 on error, 0 on success.
*/
static int
-soundcloud_parse_json(const char *url, yajl_handle hand, GMutex* mutex, GCond* cond)
+soundcloud_parse_json(const char *url, yajl_handle hand,
+ Mutex &mutex, Cond &cond)
{
struct input_stream *input_stream;
GError *error = NULL;
@@ -264,7 +260,7 @@ soundcloud_parse_json(const char *url, yajl_handle hand, GMutex* mutex, GCond* c
return -1;
}
- g_mutex_lock(mutex);
+ mutex.lock();
input_stream_wait_ready(input_stream);
yajl_status stat;
@@ -280,7 +276,7 @@ soundcloud_parse_json(const char *url, yajl_handle hand, GMutex* mutex, GCond* c
if (input_stream_eof(input_stream)) {
done = true;
} else {
- g_mutex_unlock(mutex);
+ mutex.unlock();
input_stream_close(input_stream);
return -1;
}
@@ -308,7 +304,7 @@ soundcloud_parse_json(const char *url, yajl_handle hand, GMutex* mutex, GCond* c
}
}
- g_mutex_unlock(mutex);
+ mutex.unlock();
input_stream_close(input_stream);
return 0;
@@ -323,10 +319,8 @@ soundcloud_parse_json(const char *url, yajl_handle hand, GMutex* mutex, GCond* c
*/
static struct playlist_provider *
-soundcloud_open_uri(const char *uri, GMutex *mutex, GCond *cond)
+soundcloud_open_uri(const char *uri, Mutex &mutex, Cond &cond)
{
- struct soundcloud_playlist *playlist = NULL;
-
char *s, *p;
char *scheme, *arg, *rest;
s = g_strdup(uri);
@@ -377,7 +371,6 @@ soundcloud_open_uri(const char *uri, GMutex *mutex, GCond *cond)
struct parse_data data;
data.got_url = 0;
- data.songs = NULL;
data.title = NULL;
data.stream_url = NULL;
#ifdef HAVE_YAJL1
@@ -398,34 +391,8 @@ soundcloud_open_uri(const char *uri, GMutex *mutex, GCond *cond)
if (ret == -1)
return NULL;
- playlist = g_new(struct soundcloud_playlist, 1);
- playlist_provider_init(&playlist->base, &soundcloud_playlist_plugin);
- playlist->songs = g_slist_reverse(data.songs);
-
- return &playlist->base;
-}
-
-static void
-soundcloud_close(struct playlist_provider *_playlist)
-{
- struct soundcloud_playlist *playlist = (struct soundcloud_playlist *)_playlist;
-
- g_free(playlist);
-}
-
-
-static struct song *
-soundcloud_read(struct playlist_provider *_playlist)
-{
- struct soundcloud_playlist *playlist = (struct soundcloud_playlist *)_playlist;
-
- if (playlist->songs == NULL)
- return NULL;
-
- struct song* s;
- s = (struct song *)playlist->songs->data;
- playlist->songs = g_slist_remove(playlist->songs, s);
- return s;
+ data.songs.reverse();
+ return new MemoryPlaylistProvider(std::move(data.songs));
}
static const char *const soundcloud_schemes[] = {
@@ -434,15 +401,18 @@ static const char *const soundcloud_schemes[] = {
};
const struct playlist_plugin soundcloud_playlist_plugin = {
- .name = "soundcloud",
+ "soundcloud",
- .init = soundcloud_init,
- .finish = soundcloud_finish,
- .open_uri = soundcloud_open_uri,
- .close = soundcloud_close,
- .read = soundcloud_read,
+ soundcloud_init,
+ soundcloud_finish,
+ soundcloud_open_uri,
+ nullptr,
+ nullptr,
+ nullptr,
- .schemes = soundcloud_schemes,
+ soundcloud_schemes,
+ nullptr,
+ nullptr,
};
diff --git a/src/playlist/soundcloud_playlist_plugin.h b/src/playlist/SoundCloudPlaylistPlugin.hxx
index e09e2dd4..7c121328 100644
--- a/src/playlist/soundcloud_playlist_plugin.h
+++ b/src/playlist/SoundCloudPlaylistPlugin.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -17,8 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef MPD_PLAYLIST_SOUNDCLOUD_PLAYLIST_PLUGIN_H
-#define MPD_PLAYLIST_SOUNDCLOUD_PLAYLIST_PLUGIN_H
+#ifndef MPD_SOUNDCLOUD_PLAYLIST_PLUGIN_HXX
+#define MPD_SOUNDCLOUD_PLAYLIST_PLUGIN_HXX
extern const struct playlist_plugin soundcloud_playlist_plugin;
diff --git a/src/playlist/xspf_playlist_plugin.c b/src/playlist/XspfPlaylistPlugin.cxx
index 17d9040e..bd84d86b 100644
--- a/src/playlist/xspf_playlist_plugin.c
+++ b/src/playlist/XspfPlaylistPlugin.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -18,11 +18,10 @@
*/
#include "config.h"
-#include "playlist/xspf_playlist_plugin.h"
-#include "playlist_plugin.h"
+#include "XspfPlaylistPlugin.hxx"
+#include "MemoryPlaylistProvider.hxx"
#include "input_stream.h"
#include "uri.h"
-#include "song.h"
#include "tag.h"
#include <glib.h>
@@ -36,12 +35,12 @@
/**
* This is the state object for the GLib XML parser.
*/
-struct xspf_parser {
+struct XspfParser {
/**
* The list of songs (in reverse order because that's faster
* while adding).
*/
- GSList *songs;
+ std::forward_list<SongPointer> songs;
/**
* The current position in the XML file.
@@ -63,6 +62,9 @@ struct xspf_parser {
* element.
*/
struct song *song;
+
+ XspfParser()
+ :state(ROOT) {}
};
static void
@@ -72,33 +74,33 @@ xspf_start_element(G_GNUC_UNUSED GMarkupParseContext *context,
G_GNUC_UNUSED const gchar **attribute_values,
gpointer user_data, G_GNUC_UNUSED GError **error)
{
- struct xspf_parser *parser = user_data;
+ XspfParser *parser = (XspfParser *)user_data;
switch (parser->state) {
- case ROOT:
+ case XspfParser::ROOT:
if (strcmp(element_name, "playlist") == 0)
- parser->state = PLAYLIST;
+ parser->state = XspfParser::PLAYLIST;
break;
- case PLAYLIST:
+ case XspfParser::PLAYLIST:
if (strcmp(element_name, "trackList") == 0)
- parser->state = TRACKLIST;
+ parser->state = XspfParser::TRACKLIST;
break;
- case TRACKLIST:
+ case XspfParser::TRACKLIST:
if (strcmp(element_name, "track") == 0) {
- parser->state = TRACK;
+ parser->state = XspfParser::TRACK;
parser->song = NULL;
parser->tag = TAG_NUM_OF_ITEM_TYPES;
}
break;
- case TRACK:
+ case XspfParser::TRACK:
if (strcmp(element_name, "location") == 0)
- parser->state = LOCATION;
+ parser->state = XspfParser::LOCATION;
else if (strcmp(element_name, "title") == 0)
parser->tag = TAG_TITLE;
else if (strcmp(element_name, "creator") == 0)
@@ -114,7 +116,7 @@ xspf_start_element(G_GNUC_UNUSED GMarkupParseContext *context,
break;
- case LOCATION:
+ case XspfParser::LOCATION:
break;
}
}
@@ -124,38 +126,37 @@ xspf_end_element(G_GNUC_UNUSED GMarkupParseContext *context,
const gchar *element_name,
gpointer user_data, G_GNUC_UNUSED GError **error)
{
- struct xspf_parser *parser = user_data;
+ XspfParser *parser = (XspfParser *)user_data;
switch (parser->state) {
- case ROOT:
+ case XspfParser::ROOT:
break;
- case PLAYLIST:
+ case XspfParser::PLAYLIST:
if (strcmp(element_name, "playlist") == 0)
- parser->state = ROOT;
+ parser->state = XspfParser::ROOT;
break;
- case TRACKLIST:
+ case XspfParser::TRACKLIST:
if (strcmp(element_name, "tracklist") == 0)
- parser->state = PLAYLIST;
+ parser->state = XspfParser::PLAYLIST;
break;
- case TRACK:
+ case XspfParser::TRACK:
if (strcmp(element_name, "track") == 0) {
if (parser->song != NULL)
- parser->songs = g_slist_prepend(parser->songs,
- parser->song);
+ parser->songs.emplace_front(parser->song);
- parser->state = TRACKLIST;
+ parser->state = XspfParser::TRACKLIST;
} else
parser->tag = TAG_NUM_OF_ITEM_TYPES;
break;
- case LOCATION:
- parser->state = TRACK;
+ case XspfParser::LOCATION:
+ parser->state = XspfParser::TRACK;
break;
}
}
@@ -165,15 +166,15 @@ xspf_text(G_GNUC_UNUSED GMarkupParseContext *context,
const gchar *text, gsize text_len,
gpointer user_data, G_GNUC_UNUSED GError **error)
{
- struct xspf_parser *parser = user_data;
+ XspfParser *parser = (XspfParser *)user_data;
switch (parser->state) {
- case ROOT:
- case PLAYLIST:
- case TRACKLIST:
+ case XspfParser::ROOT:
+ case XspfParser::PLAYLIST:
+ case XspfParser::TRACKLIST:
break;
- case TRACK:
+ case XspfParser::TRACK:
if (parser->song != NULL &&
parser->tag != TAG_NUM_OF_ITEM_TYPES) {
if (parser->song->tag == NULL)
@@ -184,7 +185,7 @@ xspf_text(G_GNUC_UNUSED GMarkupParseContext *context,
break;
- case LOCATION:
+ case XspfParser::LOCATION:
if (parser->song == NULL) {
char *uri = g_strndup(text, text_len);
parser->song = song_remote_new(uri);
@@ -196,29 +197,20 @@ xspf_text(G_GNUC_UNUSED GMarkupParseContext *context,
}
static const GMarkupParser xspf_parser = {
- .start_element = xspf_start_element,
- .end_element = xspf_end_element,
- .text = xspf_text,
+ xspf_start_element,
+ xspf_end_element,
+ xspf_text,
+ nullptr,
+ nullptr,
};
static void
-song_free_callback(gpointer data, G_GNUC_UNUSED gpointer user_data)
-{
- struct song *song = data;
-
- song_free(song);
-}
-
-static void
xspf_parser_destroy(gpointer data)
{
- struct xspf_parser *parser = data;
+ XspfParser *parser = (XspfParser *)data;
- if (parser->state >= TRACK && parser->song != NULL)
+ if (parser->state >= XspfParser::TRACK && parser->song != NULL)
song_free(parser->song);
-
- g_slist_foreach(parser->songs, song_free_callback, NULL);
- g_slist_free(parser->songs);
}
/*
@@ -226,20 +218,10 @@ xspf_parser_destroy(gpointer data)
*
*/
-struct xspf_playlist {
- struct playlist_provider base;
-
- GSList *songs;
-};
-
static struct playlist_provider *
xspf_open_stream(struct input_stream *is)
{
- struct xspf_parser parser = {
- .songs = NULL,
- .state = ROOT,
- };
- struct xspf_playlist *playlist;
+ XspfParser parser;
GMarkupParseContext *context;
char buffer[1024];
size_t nbytes;
@@ -284,41 +266,13 @@ xspf_open_stream(struct input_stream *is)
return NULL;
}
- /* create a #xspf_playlist object from the parsed song list */
-
- playlist = g_new(struct xspf_playlist, 1);
- playlist_provider_init(&playlist->base, &xspf_playlist_plugin);
- playlist->songs = g_slist_reverse(parser.songs);
- parser.songs = NULL;
+ parser.songs.reverse();
+ MemoryPlaylistProvider *playlist =
+ new MemoryPlaylistProvider(std::move(parser.songs));
g_markup_parse_context_free(context);
- return &playlist->base;
-}
-
-static void
-xspf_close(struct playlist_provider *_playlist)
-{
- struct xspf_playlist *playlist = (struct xspf_playlist *)_playlist;
-
- g_slist_foreach(playlist->songs, song_free_callback, NULL);
- g_slist_free(playlist->songs);
- g_free(playlist);
-}
-
-static struct song *
-xspf_read(struct playlist_provider *_playlist)
-{
- struct xspf_playlist *playlist = (struct xspf_playlist *)_playlist;
- struct song *song;
-
- if (playlist->songs == NULL)
- return NULL;
-
- song = playlist->songs->data;
- playlist->songs = g_slist_remove(playlist->songs, song);
-
- return song;
+ return playlist;
}
static const char *const xspf_suffixes[] = {
@@ -332,12 +286,16 @@ static const char *const xspf_mime_types[] = {
};
const struct playlist_plugin xspf_playlist_plugin = {
- .name = "xspf",
+ "xspf",
- .open_stream = xspf_open_stream,
- .close = xspf_close,
- .read = xspf_read,
+ nullptr,
+ nullptr,
+ nullptr,
+ xspf_open_stream,
+ nullptr,
+ nullptr,
- .suffixes = xspf_suffixes,
- .mime_types = xspf_mime_types,
+ nullptr,
+ xspf_suffixes,
+ xspf_mime_types,
};
diff --git a/src/playlist/xspf_playlist_plugin.h b/src/playlist/XspfPlaylistPlugin.hxx
index 4636d7e8..fc9bbd2c 100644
--- a/src/playlist/xspf_playlist_plugin.h
+++ b/src/playlist/XspfPlaylistPlugin.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -17,8 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef MPD_PLAYLIST_XSPF_PLAYLIST_PLUGIN_H
-#define MPD_PLAYLIST_XSPF_PLAYLIST_PLUGIN_H
+#ifndef MPD_XSPF_PLAYLIST_PLUGIN_HXX
+#define MPD_XSPF_PLAYLIST_PLUGIN_HXX
extern const struct playlist_plugin xspf_playlist_plugin;
diff --git a/src/playlist/despotify_playlist_plugin.c b/src/playlist/despotify_playlist_plugin.c
deleted file mode 100644
index 30b852c7..00000000
--- a/src/playlist/despotify_playlist_plugin.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2011 The Music Player Daemon Project
- * http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "config.h"
-#include "playlist/despotify_playlist_plugin.h"
-#include "playlist_plugin.h"
-#include "playlist_list.h"
-#include "conf.h"
-#include "uri.h"
-#include "tag.h"
-#include "song.h"
-#include "input_stream.h"
-#include "despotify_utils.h"
-
-#include <glib.h>
-
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-#include <despotify.h>
-
-struct despotify_playlist {
- struct playlist_provider base;
-
- struct despotify_session *session;
- GSList *list;
-};
-
-static void
-add_song(struct despotify_playlist *ctx, struct ds_track *track)
-{
- const char *dsp_scheme = despotify_playlist_plugin.schemes[0];
- struct song *song;
- char uri[128];
- char *ds_uri;
-
- /* Create a spt://... URI for MPD */
- g_snprintf(uri, sizeof(uri), "%s://", dsp_scheme);
- ds_uri = uri + strlen(dsp_scheme) + 3;
-
- if (despotify_track_to_uri(track, ds_uri) != ds_uri) {
- /* Should never really fail, but let's be sure */
- g_debug("Can't add track %s\n", track->title);
- return;
- }
-
- song = song_remote_new(uri);
- song->tag = mpd_despotify_tag_from_track(track);
-
- ctx->list = g_slist_prepend(ctx->list, song);
-}
-
-static bool
-parse_track(struct despotify_playlist *ctx,
- struct ds_link *link)
-{
- struct ds_track *track;
-
- track = despotify_link_get_track(ctx->session, link);
- if (!track)
- return false;
- add_song(ctx, track);
-
- return true;
-}
-
-static bool
-parse_playlist(struct despotify_playlist *ctx,
- struct ds_link *link)
-{
- struct ds_playlist *playlist;
- struct ds_track *track;
-
- playlist = despotify_link_get_playlist(ctx->session, link);
- if (!playlist)
- return false;
-
- for (track = playlist->tracks; track; track = track->next)
- add_song(ctx, track);
-
- return true;
-}
-
-static bool
-despotify_playlist_init(G_GNUC_UNUSED const struct config_param *param)
-{
- return true;
-}
-
-static void
-despotify_playlist_finish(void)
-{
-}
-
-
-static struct playlist_provider *
-despotify_playlist_open_uri(const char *url, G_GNUC_UNUSED GMutex *mutex,
- G_GNUC_UNUSED GCond *cond)
-{
- struct despotify_playlist *ctx;
- struct despotify_session *session;
- struct ds_link *link;
- bool parse_result;
-
- session = mpd_despotify_get_session();
- if (!session)
- goto clean_none;
-
- /* Get link without spt:// */
- link = despotify_link_from_uri(url + strlen(despotify_playlist_plugin.schemes[0]) + 3);
- if (!link) {
- g_debug("Can't find %s\n", url);
- goto clean_none;
- }
-
- ctx = g_new(struct despotify_playlist, 1);
-
- ctx->list = NULL;
- ctx->session = session;
- playlist_provider_init(&ctx->base, &despotify_playlist_plugin);
-
- switch (link->type)
- {
- case LINK_TYPE_TRACK:
- parse_result = parse_track(ctx, link);
- break;
- case LINK_TYPE_PLAYLIST:
- parse_result = parse_playlist(ctx, link);
- break;
- default:
- parse_result = false;
- break;
- }
- despotify_free_link(link);
- if (!parse_result)
- goto clean_playlist;
-
- ctx->list = g_slist_reverse(ctx->list);
-
- return &ctx->base;
-
-clean_playlist:
- g_slist_free(ctx->list);
-clean_none:
-
- return NULL;
-}
-
-static void
-track_free_callback(gpointer data, G_GNUC_UNUSED gpointer user_data)
-{
- struct song *song = (struct song *)data;
-
- song_free(song);
-}
-
-static void
-despotify_playlist_close(struct playlist_provider *_playlist)
-{
- struct despotify_playlist *ctx = (struct despotify_playlist *)_playlist;
-
- g_slist_foreach(ctx->list, track_free_callback, NULL);
- g_slist_free(ctx->list);
-
- g_free(ctx);
-}
-
-
-static struct song *
-despotify_playlist_read(struct playlist_provider *_playlist)
-{
- struct despotify_playlist *ctx = (struct despotify_playlist *)_playlist;
- struct song *out;
-
- if (!ctx->list)
- return NULL;
-
- /* Remove the current track */
- out = ctx->list->data;
- ctx->list = g_slist_remove(ctx->list, out);
-
- return out;
-}
-
-
-static const char *const despotify_schemes[] = {
- "spt",
- NULL
-};
-
-const struct playlist_plugin despotify_playlist_plugin = {
- .name = "despotify",
-
- .init = despotify_playlist_init,
- .finish = despotify_playlist_finish,
- .open_uri = despotify_playlist_open_uri,
- .read = despotify_playlist_read,
- .close = despotify_playlist_close,
-
- .schemes = despotify_schemes,
-};