aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am4
-rw-r--r--src/MemorySongEnumerator.cxx (renamed from src/playlist/MemoryPlaylistProvider.cxx)45
-rw-r--r--src/MemorySongEnumerator.hxx (renamed from src/playlist/MemoryPlaylistProvider.hxx)11
-rw-r--r--src/PlaylistAny.cxx7
-rw-r--r--src/PlaylistAny.hxx4
-rw-r--r--src/PlaylistMapper.cxx24
-rw-r--r--src/PlaylistMapper.hxx3
-rw-r--r--src/PlaylistPlugin.hxx42
-rw-r--r--src/PlaylistPrint.cxx12
-rw-r--r--src/PlaylistQueue.cxx13
-rw-r--r--src/PlaylistQueue.hxx4
-rw-r--r--src/PlaylistRegistry.cxx42
-rw-r--r--src/PlaylistRegistry.hxx8
-rw-r--r--src/SongEnumerator.hxx41
-rw-r--r--src/playlist/AsxPlaylistPlugin.cxx11
-rw-r--r--src/playlist/CuePlaylistPlugin.cxx43
-rw-r--r--src/playlist/DespotifyPlaylistPlugin.cxx9
-rw-r--r--src/playlist/EmbeddedCuePlaylistPlugin.cxx38
-rw-r--r--src/playlist/ExtM3uPlaylistPlugin.cxx40
-rw-r--r--src/playlist/LastFMPlaylistPlugin.cxx42
-rw-r--r--src/playlist/M3uPlaylistPlugin.cxx32
-rw-r--r--src/playlist/PlsPlaylistPlugin.cxx9
-rw-r--r--src/playlist/RssPlaylistPlugin.cxx11
-rw-r--r--src/playlist/SoundCloudPlaylistPlugin.cxx9
-rw-r--r--src/playlist/XspfPlaylistPlugin.cxx11
-rw-r--r--test/dump_playlist.cxx8
26 files changed, 206 insertions, 317 deletions
diff --git a/Makefile.am b/Makefile.am
index 862acac05..6def54a3a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -917,8 +917,8 @@ endif
libplaylist_plugins_a_SOURCES = \
src/PlaylistPlugin.hxx \
- src/playlist/MemoryPlaylistProvider.cxx \
- src/playlist/MemoryPlaylistProvider.hxx \
+ src/SongEnumerator.hxx \
+ src/MemorySongEnumerator.cxx src/MemorySongEnumerator.hxx \
src/playlist/ExtM3uPlaylistPlugin.cxx \
src/playlist/ExtM3uPlaylistPlugin.hxx \
src/playlist/M3uPlaylistPlugin.cxx \
diff --git a/src/playlist/MemoryPlaylistProvider.cxx b/src/MemorySongEnumerator.cxx
index c2b6d9312..7c9d05daa 100644
--- a/src/playlist/MemoryPlaylistProvider.cxx
+++ b/src/MemorySongEnumerator.cxx
@@ -18,50 +18,13 @@
*/
#include "config.h"
-#include "MemoryPlaylistProvider.hxx"
-#include "Song.hxx"
+#include "MemorySongEnumerator.hxx"
-static void
-memory_playlist_close(struct playlist_provider *_playlist)
-{
- MemoryPlaylistProvider *playlist = (MemoryPlaylistProvider *)_playlist;
-
- delete playlist;
-}
-
-static 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()
+Song *
+MemorySongEnumerator::NextSong()
{
if (songs.empty())
- return NULL;
+ return nullptr;
auto result = songs.front().Steal();
songs.pop_front();
diff --git a/src/playlist/MemoryPlaylistProvider.hxx b/src/MemorySongEnumerator.hxx
index efbc46fe1..46086a064 100644
--- a/src/playlist/MemoryPlaylistProvider.hxx
+++ b/src/MemorySongEnumerator.hxx
@@ -20,20 +20,19 @@
#ifndef MPD_MEMORY_PLAYLIST_PROVIDER_HXX
#define MPD_MEMORY_PLAYLIST_PROVIDER_HXX
-#include "PlaylistPlugin.hxx"
+#include "SongEnumerator.hxx"
#include "SongPointer.hxx"
#include <forward_list>
-struct Song;
-
-class MemoryPlaylistProvider : public playlist_provider {
+class MemorySongEnumerator final : public SongEnumerator {
std::forward_list<SongPointer> songs;
public:
- MemoryPlaylistProvider(std::forward_list<SongPointer> &&_songs);
+ MemorySongEnumerator(std::forward_list<SongPointer> &&_songs)
+ :songs(std::move(_songs)) {}
- Song *Read();
+ virtual Song *NextSong() override;
};
#endif
diff --git a/src/PlaylistAny.cxx b/src/PlaylistAny.cxx
index e84d055bd..95f65dca5 100644
--- a/src/PlaylistAny.cxx
+++ b/src/PlaylistAny.cxx
@@ -27,14 +27,13 @@
#include <assert.h>
-static struct playlist_provider *
+static SongEnumerator *
playlist_open_remote(const char *uri, Mutex &mutex, Cond &cond,
struct input_stream **is_r)
{
assert(uri_has_scheme(uri));
- struct playlist_provider *playlist =
- playlist_list_open_uri(uri, mutex, cond);
+ SongEnumerator *playlist = playlist_list_open_uri(uri, mutex, cond);
if (playlist != NULL) {
*is_r = NULL;
return playlist;
@@ -60,7 +59,7 @@ playlist_open_remote(const char *uri, Mutex &mutex, Cond &cond,
return playlist;
}
-struct playlist_provider *
+SongEnumerator *
playlist_open_any(const char *uri, Mutex &mutex, Cond &cond,
struct input_stream **is_r)
{
diff --git a/src/PlaylistAny.hxx b/src/PlaylistAny.hxx
index d69087b3f..951fa1099 100644
--- a/src/PlaylistAny.hxx
+++ b/src/PlaylistAny.hxx
@@ -23,7 +23,7 @@
#include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
-struct playlist_provider;
+class SongEnumerator;
struct input_stream;
/**
@@ -35,7 +35,7 @@ struct input_stream;
* here, which must be closed after the playlist_provider object is
* freed
*/
-struct playlist_provider *
+SongEnumerator *
playlist_open_any(const char *uri, Mutex &mutex, Cond &cond,
struct input_stream **is_r);
diff --git a/src/PlaylistMapper.cxx b/src/PlaylistMapper.cxx
index 08131106d..559154a4e 100644
--- a/src/PlaylistMapper.cxx
+++ b/src/PlaylistMapper.cxx
@@ -27,13 +27,11 @@
#include <assert.h>
-static struct playlist_provider *
+static SongEnumerator *
playlist_open_path(const char *path_fs, Mutex &mutex, Cond &cond,
struct input_stream **is_r)
{
- struct playlist_provider *playlist;
-
- playlist = playlist_list_open_uri(path_fs, mutex, cond);
+ auto playlist = playlist_list_open_uri(path_fs, mutex, cond);
if (playlist != NULL)
*is_r = NULL;
else
@@ -45,7 +43,7 @@ playlist_open_path(const char *path_fs, Mutex &mutex, Cond &cond,
/**
* Load a playlist from the configured playlist directory.
*/
-static struct playlist_provider *
+static SongEnumerator *
playlist_open_in_playlist_dir(const char *uri, Mutex &mutex, Cond &cond,
struct input_stream **is_r)
{
@@ -59,8 +57,7 @@ playlist_open_in_playlist_dir(const char *uri, Mutex &mutex, Cond &cond,
path_fs = g_build_filename(playlist_directory_fs.c_str(), uri, NULL);
- struct playlist_provider *playlist =
- playlist_open_path(path_fs, mutex, cond, is_r);
+ auto playlist = playlist_open_path(path_fs, mutex, cond, is_r);
g_free(path_fs);
return playlist;
@@ -69,7 +66,7 @@ playlist_open_in_playlist_dir(const char *uri, Mutex &mutex, Cond &cond,
/**
* Load a playlist from the configured music directory.
*/
-static struct playlist_provider *
+static SongEnumerator *
playlist_open_in_music_dir(const char *uri, Mutex &mutex, Cond &cond,
struct input_stream **is_r)
{
@@ -82,21 +79,20 @@ playlist_open_in_music_dir(const char *uri, Mutex &mutex, Cond &cond,
return playlist_open_path(path.c_str(), mutex, cond, is_r);
}
-struct playlist_provider *
+SongEnumerator *
playlist_mapper_open(const char *uri, Mutex &mutex, Cond &cond,
struct input_stream **is_r)
{
- struct playlist_provider *playlist;
-
if (spl_valid_name(uri)) {
- playlist = playlist_open_in_playlist_dir(uri, mutex, cond,
- is_r);
+ auto playlist = playlist_open_in_playlist_dir(uri, mutex, cond,
+ is_r);
if (playlist != NULL)
return playlist;
}
if (uri_safe_local(uri)) {
- playlist = playlist_open_in_music_dir(uri, mutex, cond, is_r);
+ auto playlist = playlist_open_in_music_dir(uri, mutex, cond,
+ is_r);
if (playlist != NULL)
return playlist;
}
diff --git a/src/PlaylistMapper.hxx b/src/PlaylistMapper.hxx
index abfdb5481..b966e6c39 100644
--- a/src/PlaylistMapper.hxx
+++ b/src/PlaylistMapper.hxx
@@ -23,6 +23,7 @@
#include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
+class SongEnumerator;
struct input_stream;
/**
@@ -33,7 +34,7 @@ struct input_stream;
* here, which must be closed after the playlist_provider object is
* freed
*/
-struct playlist_provider *
+SongEnumerator *
playlist_mapper_open(const char *uri, Mutex &mutex, Cond &cond,
struct input_stream **is_r);
diff --git a/src/PlaylistPlugin.hxx b/src/PlaylistPlugin.hxx
index f89fd9ce0..ce380d886 100644
--- a/src/PlaylistPlugin.hxx
+++ b/src/PlaylistPlugin.hxx
@@ -26,21 +26,7 @@
struct config_param;
struct input_stream;
struct Tag;
-struct Song;
-
-/**
- * An object which provides the contents of a playlist.
- */
-struct playlist_provider {
- const struct playlist_plugin *plugin;
-};
-
-static inline void
-playlist_provider_init(struct playlist_provider *playlist,
- const struct playlist_plugin *plugin)
-{
- playlist->plugin = plugin;
-}
+class SongEnumerator;
struct playlist_plugin {
const char *name;
@@ -65,19 +51,15 @@ struct playlist_plugin {
* Opens the playlist on the specified URI. This URI has
* either matched one of the schemes or one of the suffixes.
*/
- struct playlist_provider *(*open_uri)(const char *uri,
- Mutex &mutex, Cond &cond);
+ SongEnumerator *(*open_uri)(const char *uri,
+ Mutex &mutex, Cond &cond);
/**
* Opens the playlist in the specified input stream. It has
* either matched one of the suffixes or one of the MIME
* types.
*/
- struct playlist_provider *(*open_stream)(struct input_stream *is);
-
- void (*close)(struct playlist_provider *playlist);
-
- Song *(*read)(struct playlist_provider *playlist);
+ SongEnumerator *(*open_stream)(struct input_stream *is);
const char *const*schemes;
const char *const*suffixes;
@@ -111,30 +93,18 @@ playlist_plugin_finish(const struct playlist_plugin *plugin)
plugin->finish();
}
-static inline struct playlist_provider *
+static inline SongEnumerator *
playlist_plugin_open_uri(const struct playlist_plugin *plugin, const char *uri,
Mutex &mutex, Cond &cond)
{
return plugin->open_uri(uri, mutex, cond);
}
-static inline struct playlist_provider *
+static inline SongEnumerator *
playlist_plugin_open_stream(const struct playlist_plugin *plugin,
struct input_stream *is)
{
return plugin->open_stream(is);
}
-static inline void
-playlist_plugin_close(struct playlist_provider *playlist)
-{
- playlist->plugin->close(playlist);
-}
-
-static inline Song *
-playlist_plugin_read(struct playlist_provider *playlist)
-{
- return playlist->plugin->read(playlist);
-}
-
#endif
diff --git a/src/PlaylistPrint.cxx b/src/PlaylistPrint.cxx
index f95061ca5..012f9600b 100644
--- a/src/PlaylistPrint.cxx
+++ b/src/PlaylistPrint.cxx
@@ -26,6 +26,7 @@
#include "PlaylistRegistry.hxx"
#include "PlaylistPlugin.hxx"
#include "QueuePrint.hxx"
+#include "SongEnumerator.hxx"
#include "SongPrint.hxx"
#include "DatabaseGlue.hxx"
#include "DatabasePlugin.hxx"
@@ -145,12 +146,12 @@ spl_print(Client *client, const char *name_utf8, bool detail,
static void
playlist_provider_print(Client *client, const char *uri,
- struct playlist_provider *playlist, bool detail)
+ SongEnumerator &e, bool detail)
{
Song *song;
char *base_uri = uri != NULL ? g_path_get_dirname(uri) : NULL;
- while ((song = playlist_plugin_read(playlist)) != NULL) {
+ while ((song = e.NextSong()) != nullptr) {
song = playlist_check_translate_song(song, base_uri, false);
if (song == NULL)
continue;
@@ -173,13 +174,12 @@ playlist_file_print(Client *client, const char *uri, bool detail)
Cond cond;
struct input_stream *is;
- struct playlist_provider *playlist =
- playlist_open_any(uri, mutex, cond, &is);
+ SongEnumerator *playlist = playlist_open_any(uri, mutex, cond, &is);
if (playlist == NULL)
return false;
- playlist_provider_print(client, uri, playlist, detail);
- playlist_plugin_close(playlist);
+ playlist_provider_print(client, uri, *playlist, detail);
+ delete playlist;
if (is != NULL)
is->Close();
diff --git a/src/PlaylistQueue.cxx b/src/PlaylistQueue.cxx
index af68176fe..901ee578d 100644
--- a/src/PlaylistQueue.cxx
+++ b/src/PlaylistQueue.cxx
@@ -24,10 +24,11 @@
#include "PlaylistSong.hxx"
#include "Playlist.hxx"
#include "InputStream.hxx"
+#include "SongEnumerator.hxx"
#include "Song.hxx"
enum playlist_result
-playlist_load_into_queue(const char *uri, struct playlist_provider *source,
+playlist_load_into_queue(const char *uri, SongEnumerator &e,
unsigned start_index, unsigned end_index,
struct playlist *dest, struct player_control *pc,
bool secure)
@@ -37,7 +38,7 @@ playlist_load_into_queue(const char *uri, struct playlist_provider *source,
char *base_uri = uri != NULL ? g_path_get_dirname(uri) : NULL;
for (unsigned i = 0;
- i < end_index && (song = playlist_plugin_read(source)) != NULL;
+ i < end_index && (song = e.NextSong()) != NULL;
++i) {
if (i < start_index) {
/* skip songs before the start index */
@@ -72,15 +73,15 @@ playlist_open_into_queue(const char *uri,
Cond cond;
struct input_stream *is;
- struct playlist_provider *playlist =
- playlist_open_any(uri, mutex, cond, &is);
+ auto playlist = playlist_open_any(uri, mutex, cond, &is);
if (playlist == NULL)
return PLAYLIST_RESULT_NO_SUCH_LIST;
enum playlist_result result =
- playlist_load_into_queue(uri, playlist, start_index, end_index,
+ playlist_load_into_queue(uri, *playlist,
+ start_index, end_index,
dest, pc, secure);
- playlist_plugin_close(playlist);
+ delete playlist;
if (is != NULL)
is->Close();
diff --git a/src/PlaylistQueue.hxx b/src/PlaylistQueue.hxx
index 5a5cc641d..71768ecb4 100644
--- a/src/PlaylistQueue.hxx
+++ b/src/PlaylistQueue.hxx
@@ -26,7 +26,7 @@
#include "PlaylistError.hxx"
-struct playlist_provider;
+class SongEnumerator;
struct playlist;
struct player_control;
@@ -40,7 +40,7 @@ struct player_control;
* @param end_index the index of the last song (excluding)
*/
enum playlist_result
-playlist_load_into_queue(const char *uri, struct playlist_provider *source,
+playlist_load_into_queue(const char *uri, SongEnumerator &e,
unsigned start_index, unsigned end_index,
struct playlist *dest, struct player_control *pc,
bool secure);
diff --git a/src/PlaylistRegistry.cxx b/src/PlaylistRegistry.cxx
index 375e51d83..88628e455 100644
--- a/src/PlaylistRegistry.cxx
+++ b/src/PlaylistRegistry.cxx
@@ -124,12 +124,12 @@ playlist_list_global_finish(void)
playlist_plugin_finish(plugin);
}
-static struct playlist_provider *
+static SongEnumerator *
playlist_list_open_uri_scheme(const char *uri, Mutex &mutex, Cond &cond,
bool *tried)
{
char *scheme;
- struct playlist_provider *playlist = NULL;
+ SongEnumerator *playlist = nullptr;
assert(uri != NULL);
@@ -158,12 +158,12 @@ playlist_list_open_uri_scheme(const char *uri, Mutex &mutex, Cond &cond,
return playlist;
}
-static struct playlist_provider *
+static SongEnumerator *
playlist_list_open_uri_suffix(const char *uri, Mutex &mutex, Cond &cond,
const bool *tried)
{
const char *suffix;
- struct playlist_provider *playlist = NULL;
+ SongEnumerator *playlist = nullptr;
assert(uri != NULL);
@@ -187,10 +187,9 @@ playlist_list_open_uri_suffix(const char *uri, Mutex &mutex, Cond &cond,
return playlist;
}
-struct playlist_provider *
+SongEnumerator *
playlist_list_open_uri(const char *uri, Mutex &mutex, Cond &cond)
{
- struct playlist_provider *playlist;
/** this array tracks which plugins have already been tried by
playlist_list_open_uri_scheme() */
bool tried[G_N_ELEMENTS(playlist_plugins) - 1];
@@ -199,7 +198,7 @@ playlist_list_open_uri(const char *uri, Mutex &mutex, Cond &cond)
memset(tried, false, sizeof(tried));
- playlist = playlist_list_open_uri_scheme(uri, mutex, cond, tried);
+ auto playlist = playlist_list_open_uri_scheme(uri, mutex, cond, tried);
if (playlist == NULL)
playlist = playlist_list_open_uri_suffix(uri, mutex, cond,
tried);
@@ -207,11 +206,9 @@ playlist_list_open_uri(const char *uri, Mutex &mutex, Cond &cond)
return playlist;
}
-static struct playlist_provider *
+static SongEnumerator *
playlist_list_open_stream_mime2(struct input_stream *is, const char *mime)
{
- struct playlist_provider *playlist;
-
assert(is != NULL);
assert(mime != NULL);
@@ -223,7 +220,7 @@ playlist_list_open_stream_mime2(struct input_stream *is, const char *mime)
fresh start */
is->Seek(0, SEEK_SET, IgnoreError());
- playlist = playlist_plugin_open_stream(plugin, is);
+ auto playlist = playlist_plugin_open_stream(plugin, is);
if (playlist != NULL)
return playlist;
}
@@ -232,7 +229,7 @@ playlist_list_open_stream_mime2(struct input_stream *is, const char *mime)
return NULL;
}
-static struct playlist_provider *
+static SongEnumerator *
playlist_list_open_stream_mime(struct input_stream *is, const char *full_mime)
{
assert(full_mime != NULL);
@@ -246,17 +243,14 @@ playlist_list_open_stream_mime(struct input_stream *is, const char *full_mime)
/* probe only the portion before the semicolon*/
char *mime = g_strndup(full_mime, semicolon - full_mime);
- struct playlist_provider *playlist =
- playlist_list_open_stream_mime2(is, mime);
+ auto playlist = playlist_list_open_stream_mime2(is, mime);
g_free(mime);
return playlist;
}
-static struct playlist_provider *
+static SongEnumerator *
playlist_list_open_stream_suffix(struct input_stream *is, const char *suffix)
{
- struct playlist_provider *playlist;
-
assert(is != NULL);
assert(suffix != NULL);
@@ -268,7 +262,7 @@ playlist_list_open_stream_suffix(struct input_stream *is, const char *suffix)
fresh start */
is->Seek(0, SEEK_SET, IgnoreError());
- playlist = playlist_plugin_open_stream(plugin, is);
+ auto playlist = playlist_plugin_open_stream(plugin, is);
if (playlist != NULL)
return playlist;
}
@@ -277,24 +271,23 @@ playlist_list_open_stream_suffix(struct input_stream *is, const char *suffix)
return NULL;
}
-struct playlist_provider *
+SongEnumerator *
playlist_list_open_stream(struct input_stream *is, const char *uri)
{
const char *suffix;
- struct playlist_provider *playlist;
is->LockWaitReady();
const char *const mime = is->GetMimeType();
if (mime != NULL) {
- playlist = playlist_list_open_stream_mime(is, mime);
+ auto playlist = playlist_list_open_stream_mime(is, mime);
if (playlist != NULL)
return playlist;
}
suffix = uri != NULL ? uri_get_suffix(uri) : NULL;
if (suffix != NULL) {
- playlist = playlist_list_open_stream_suffix(is, suffix);
+ auto playlist = playlist_list_open_stream_suffix(is, suffix);
if (playlist != NULL)
return playlist;
}
@@ -316,12 +309,11 @@ playlist_suffix_supported(const char *suffix)
return false;
}
-struct playlist_provider *
+SongEnumerator *
playlist_list_open_path(const char *path_fs, Mutex &mutex, Cond &cond,
struct input_stream **is_r)
{
const char *suffix;
- struct playlist_provider *playlist;
assert(path_fs != NULL);
@@ -340,7 +332,7 @@ playlist_list_open_path(const char *path_fs, Mutex &mutex, Cond &cond,
is->LockWaitReady();
- playlist = playlist_list_open_stream_suffix(is, suffix);
+ auto playlist = playlist_list_open_stream_suffix(is, suffix);
if (playlist != NULL)
*is_r = is;
else
diff --git a/src/PlaylistRegistry.hxx b/src/PlaylistRegistry.hxx
index 7c34c1565..350987012 100644
--- a/src/PlaylistRegistry.hxx
+++ b/src/PlaylistRegistry.hxx
@@ -23,7 +23,7 @@
#include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
-struct playlist_provider;
+class SongEnumerator;
struct input_stream;
extern const struct playlist_plugin *const playlist_plugins[];
@@ -49,7 +49,7 @@ playlist_list_global_finish(void);
/**
* Opens a playlist by its URI.
*/
-struct playlist_provider *
+SongEnumerator *
playlist_list_open_uri(const char *uri, Mutex &mutex, Cond &cond);
/**
@@ -59,7 +59,7 @@ playlist_list_open_uri(const char *uri, Mutex &mutex, Cond &cond);
* @param uri optional URI which was used to open the stream; may be
* used to select the appropriate playlist plugin
*/
-struct playlist_provider *
+SongEnumerator *
playlist_list_open_stream(struct input_stream *is, const char *uri);
/**
@@ -77,7 +77,7 @@ playlist_suffix_supported(const char *suffix);
* which must be closed after the playlist_provider object is freed
* @return a playlist, or NULL on error
*/
-struct playlist_provider *
+SongEnumerator *
playlist_list_open_path(const char *path_fs, Mutex &mutex, Cond &cond,
struct input_stream **is_r);
diff --git a/src/SongEnumerator.hxx b/src/SongEnumerator.hxx
new file mode 100644
index 000000000..0e268a31a
--- /dev/null
+++ b/src/SongEnumerator.hxx
@@ -0,0 +1,41 @@
+/*
+ * 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_SONG_ENUMERATOR_HXX
+#define MPD_SONG_ENUMERATOR_HXX
+
+struct Song;
+
+/**
+ * An object which provides serial access to a number of #Song
+ * objects. It is used to enumerate the contents of a playlist file.
+ */
+class SongEnumerator {
+public:
+ virtual ~SongEnumerator() {}
+
+ /**
+ * Obtain the next song. The caller is responsible for
+ * freeing the returned #Song object. Returns nullptr if
+ * there are no more songs.
+ */
+ virtual Song *NextSong() = 0;
+};
+
+#endif
diff --git a/src/playlist/AsxPlaylistPlugin.cxx b/src/playlist/AsxPlaylistPlugin.cxx
index c0fc15e07..6920ec268 100644
--- a/src/playlist/AsxPlaylistPlugin.cxx
+++ b/src/playlist/AsxPlaylistPlugin.cxx
@@ -19,7 +19,8 @@
#include "config.h"
#include "AsxPlaylistPlugin.hxx"
-#include "MemoryPlaylistProvider.hxx"
+#include "PlaylistPlugin.hxx"
+#include "MemorySongEnumerator.hxx"
#include "InputStream.hxx"
#include "Song.hxx"
#include "Tag.hxx"
@@ -201,7 +202,7 @@ asx_parser_destroy(gpointer data)
*
*/
-static struct playlist_provider *
+static SongEnumerator *
asx_open_stream(struct input_stream *is)
{
AsxParser parser;
@@ -249,8 +250,8 @@ asx_open_stream(struct input_stream *is)
}
parser.songs.reverse();
- MemoryPlaylistProvider *playlist =
- new MemoryPlaylistProvider(std::move(parser.songs));
+ MemorySongEnumerator *playlist =
+ new MemorySongEnumerator(std::move(parser.songs));
g_markup_parse_context_free(context);
@@ -274,8 +275,6 @@ const struct playlist_plugin asx_playlist_plugin = {
nullptr,
nullptr,
asx_open_stream,
- nullptr,
- nullptr,
nullptr,
asx_suffixes,
diff --git a/src/playlist/CuePlaylistPlugin.cxx b/src/playlist/CuePlaylistPlugin.cxx
index aa84b1c4a..1c1433a6a 100644
--- a/src/playlist/CuePlaylistPlugin.cxx
+++ b/src/playlist/CuePlaylistPlugin.cxx
@@ -20,67 +20,54 @@
#include "config.h"
#include "CuePlaylistPlugin.hxx"
#include "PlaylistPlugin.hxx"
+#include "SongEnumerator.hxx"
#include "Tag.hxx"
#include "Song.hxx"
#include "cue/CueParser.hxx"
#include "TextInputStream.hxx"
-#include <glib.h>
#include <assert.h>
#include <string.h>
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "cue"
-struct CuePlaylist {
- struct playlist_provider base;
-
+class CuePlaylist final : public SongEnumerator {
struct input_stream *is;
TextInputStream tis;
CueParser parser;
+ public:
CuePlaylist(struct input_stream *_is)
:is(_is), tis(is) {
- playlist_provider_init(&base, &cue_playlist_plugin);
}
- ~CuePlaylist() {
- }
+ virtual Song *NextSong() override;
};
-static struct playlist_provider *
+static SongEnumerator *
cue_playlist_open_stream(struct input_stream *is)
{
- CuePlaylist *playlist = new CuePlaylist(is);
- return &playlist->base;
-}
-
-static void
-cue_playlist_close(struct playlist_provider *_playlist)
-{
- CuePlaylist *playlist = (CuePlaylist *)_playlist;
- delete playlist;
+ return new CuePlaylist(is);
}
-static Song *
-cue_playlist_read(struct playlist_provider *_playlist)
+Song *
+CuePlaylist::NextSong()
{
- CuePlaylist *playlist = (CuePlaylist *)_playlist;
-
- Song *song = playlist->parser.Get();
+ Song *song = parser.Get();
if (song != NULL)
return song;
std::string line;
- while (playlist->tis.ReadLine(line)) {
- playlist->parser.Feed(line.c_str());
- song = playlist->parser.Get();
+ while (tis.ReadLine(line)) {
+ parser.Feed(line.c_str());
+ song = parser.Get();
if (song != NULL)
return song;
}
- playlist->parser.Finish();
- return playlist->parser.Get();
+ parser.Finish();
+ return parser.Get();
}
static const char *const cue_playlist_suffixes[] = {
@@ -100,8 +87,6 @@ const struct playlist_plugin cue_playlist_plugin = {
nullptr,
nullptr,
cue_playlist_open_stream,
- cue_playlist_close,
- cue_playlist_read,
nullptr,
cue_playlist_suffixes,
diff --git a/src/playlist/DespotifyPlaylistPlugin.cxx b/src/playlist/DespotifyPlaylistPlugin.cxx
index 5759a10c0..3e6527ea7 100644
--- a/src/playlist/DespotifyPlaylistPlugin.cxx
+++ b/src/playlist/DespotifyPlaylistPlugin.cxx
@@ -20,7 +20,8 @@
#include "config.h"
#include "DespotifyPlaylistPlugin.hxx"
#include "DespotifyUtils.hxx"
-#include "MemoryPlaylistProvider.hxx"
+#include "PlaylistPlugin.hxx"
+#include "MemorySongEnumerator.hxx"
#include "Tag.hxx"
#include "Song.hxx"
@@ -86,7 +87,7 @@ parse_playlist(struct despotify_session *session,
return true;
}
-static struct playlist_provider *
+static SongEnumerator *
despotify_playlist_open_uri(const char *url,
gcc_unused Mutex &mutex, gcc_unused Cond &cond)
{
@@ -122,7 +123,7 @@ despotify_playlist_open_uri(const char *url,
return nullptr;
songs.reverse();
- return new MemoryPlaylistProvider(std::move(songs));
+ return new MemorySongEnumerator(std::move(songs));
}
static const char *const despotify_schemes[] = {
@@ -137,8 +138,6 @@ const struct playlist_plugin despotify_playlist_plugin = {
nullptr,
despotify_playlist_open_uri,
nullptr,
- nullptr,
- nullptr,
despotify_schemes,
nullptr,
diff --git a/src/playlist/EmbeddedCuePlaylistPlugin.cxx b/src/playlist/EmbeddedCuePlaylistPlugin.cxx
index 237bccdd5..8c5309ac1 100644
--- a/src/playlist/EmbeddedCuePlaylistPlugin.cxx
+++ b/src/playlist/EmbeddedCuePlaylistPlugin.cxx
@@ -26,6 +26,7 @@
#include "config.h"
#include "EmbeddedCuePlaylistPlugin.hxx"
#include "PlaylistPlugin.hxx"
+#include "SongEnumerator.hxx"
#include "Tag.hxx"
#include "TagHandler.hxx"
#include "tag/TagId3.hxx"
@@ -41,9 +42,8 @@
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "cue"
-struct EmbeddedCuePlaylist {
- struct playlist_provider base;
-
+class EmbeddedCuePlaylist final : public SongEnumerator {
+public:
/**
* This is an override for the CUE's "FILE". An embedded CUE
* sheet must always point to the song file it is contained
@@ -63,18 +63,18 @@ struct EmbeddedCuePlaylist {
CueParser *parser;
+public:
EmbeddedCuePlaylist()
:filename(nullptr), cuesheet(nullptr), parser(nullptr) {
- playlist_provider_init(&base, &embcue_playlist_plugin);
}
- ~EmbeddedCuePlaylist() {
+ virtual ~EmbeddedCuePlaylist() {
delete parser;
g_free(cuesheet);
g_free(filename);
}
- Song *Read();
+ virtual Song *NextSong() override;
};
static void
@@ -93,7 +93,7 @@ static const struct tag_handler embcue_tag_handler = {
embcue_tag_pair,
};
-static struct playlist_provider *
+static SongEnumerator *
embcue_playlist_open_uri(const char *uri,
gcc_unused Mutex &mutex,
gcc_unused Cond &cond)
@@ -122,19 +122,11 @@ embcue_playlist_open_uri(const char *uri,
playlist->next = playlist->cuesheet;
playlist->parser = new CueParser();
- return &playlist->base;
-}
-
-static void
-embcue_playlist_close(struct playlist_provider *_playlist)
-{
- EmbeddedCuePlaylist *playlist = (EmbeddedCuePlaylist *)_playlist;
-
- delete playlist;
+ return playlist;
}
-inline Song *
-EmbeddedCuePlaylist::Read()
+Song *
+EmbeddedCuePlaylist::NextSong()
{
Song *song = parser->Get();
if (song != NULL)
@@ -165,14 +157,6 @@ EmbeddedCuePlaylist::Read()
return song;
}
-static Song *
-embcue_playlist_read(struct playlist_provider *_playlist)
-{
- EmbeddedCuePlaylist *playlist = (EmbeddedCuePlaylist *)_playlist;
-
- return playlist->Read();
-}
-
static const char *const embcue_playlist_suffixes[] = {
/* a few codecs that are known to be supported; there are
probably many more */
@@ -192,8 +176,6 @@ const struct playlist_plugin embcue_playlist_plugin = {
nullptr,
embcue_playlist_open_uri,
nullptr,
- embcue_playlist_close,
- embcue_playlist_read,
embcue_playlist_suffixes,
nullptr,
diff --git a/src/playlist/ExtM3uPlaylistPlugin.cxx b/src/playlist/ExtM3uPlaylistPlugin.cxx
index 440dcd432..ff3fcbd7e 100644
--- a/src/playlist/ExtM3uPlaylistPlugin.cxx
+++ b/src/playlist/ExtM3uPlaylistPlugin.cxx
@@ -20,6 +20,7 @@
#include "config.h"
#include "ExtM3uPlaylistPlugin.hxx"
#include "PlaylistPlugin.hxx"
+#include "SongEnumerator.hxx"
#include "Song.hxx"
#include "Tag.hxx"
#include "util/StringUtil.hxx"
@@ -30,40 +31,36 @@
#include <string.h>
#include <stdlib.h>
-struct ExtM3uPlaylist {
- struct playlist_provider base;
-
+class ExtM3uPlaylist final : public SongEnumerator {
TextInputStream tis;
+public:
ExtM3uPlaylist(input_stream *is)
:tis(is) {
- playlist_provider_init(&base, &extm3u_playlist_plugin);
}
+
+ bool CheckFirstLine() {
+ std::string line;
+ return tis.ReadLine(line) &&
+ strcmp(line.c_str(), "#EXTM3U") == 0;
+ }
+
+ virtual Song *NextSong() override;
};
-static struct playlist_provider *
+static SongEnumerator *
extm3u_open_stream(struct input_stream *is)
{
ExtM3uPlaylist *playlist = new ExtM3uPlaylist(is);
- std::string line;
- if (!playlist->tis.ReadLine(line)
- || strcmp(line.c_str(), "#EXTM3U") != 0) {
+ if (!playlist->CheckFirstLine()) {
/* no EXTM3U header: fall back to the plain m3u
plugin */
delete playlist;
return NULL;
}
- return &playlist->base;
-}
-
-static void
-extm3u_close(struct playlist_provider *_playlist)
-{
- ExtM3uPlaylist *playlist = (ExtM3uPlaylist *)_playlist;
-
- delete playlist;
+ return playlist;
}
/**
@@ -106,17 +103,16 @@ extm3u_parse_tag(const char *line)
return tag;
}
-static Song *
-extm3u_read(struct playlist_provider *_playlist)
+Song *
+ExtM3uPlaylist::NextSong()
{
- ExtM3uPlaylist *playlist = (ExtM3uPlaylist *)_playlist;
Tag *tag = NULL;
std::string line;
const char *line_s;
Song *song;
do {
- if (!playlist->tis.ReadLine(line)) {
+ if (!tis.ReadLine(line)) {
delete tag;
return NULL;
}
@@ -155,8 +151,6 @@ const struct playlist_plugin extm3u_playlist_plugin = {
nullptr,
nullptr,
extm3u_open_stream,
- extm3u_close,
- extm3u_read,
nullptr,
extm3u_suffixes,
diff --git a/src/playlist/LastFMPlaylistPlugin.cxx b/src/playlist/LastFMPlaylistPlugin.cxx
index a727a21a4..2cc538e1e 100644
--- a/src/playlist/LastFMPlaylistPlugin.cxx
+++ b/src/playlist/LastFMPlaylistPlugin.cxx
@@ -21,6 +21,7 @@
#include "LastFMPlaylistPlugin.hxx"
#include "PlaylistPlugin.hxx"
#include "PlaylistRegistry.hxx"
+#include "SongEnumerator.hxx"
#include "ConfigData.hxx"
#include "Song.hxx"
#include "InputStream.hxx"
@@ -31,22 +32,24 @@
#include <assert.h>
#include <string.h>
-struct LastfmPlaylist {
- struct playlist_provider base;
-
+class LastfmPlaylist final : public SongEnumerator {
struct input_stream *is;
- struct playlist_provider *xspf;
+ SongEnumerator *const xspf;
- LastfmPlaylist(input_stream *_is, playlist_provider *_xspf)
+public:
+ LastfmPlaylist(input_stream *_is, SongEnumerator *_xspf)
:is(_is), xspf(_xspf) {
- playlist_provider_init(&base, &lastfm_playlist_plugin);
}
- ~LastfmPlaylist() {
- playlist_plugin_close(xspf);
+ virtual ~LastfmPlaylist() {
+ delete xspf;
is->Close();
}
+
+ virtual Song *NextSong() override {
+ return xspf->NextSong();
+ }
};
static struct {
@@ -161,7 +164,7 @@ lastfm_find(const char *response, const char *name)
}
}
-static struct playlist_provider *
+static SongEnumerator *
lastfm_open_uri(const char *uri, Mutex &mutex, Cond &cond)
{
char *p, *q, *response, *session;
@@ -256,24 +259,7 @@ lastfm_open_uri(const char *uri, Mutex &mutex, Cond &cond)
/* create the playlist object */
- const auto playlist = new LastfmPlaylist(is, xspf);
- return &playlist->base;
-}
-
-static void
-lastfm_close(struct playlist_provider *_playlist)
-{
- LastfmPlaylist *playlist = (LastfmPlaylist *)_playlist;
-
- delete playlist;
-}
-
-static Song *
-lastfm_read(struct playlist_provider *_playlist)
-{
- LastfmPlaylist *playlist = (LastfmPlaylist *)_playlist;
-
- return playlist_plugin_read(playlist->xspf);
+ return new LastfmPlaylist(is, xspf);
}
static const char *const lastfm_schemes[] = {
@@ -288,8 +274,6 @@ const struct playlist_plugin lastfm_playlist_plugin = {
lastfm_finish,
lastfm_open_uri,
nullptr,
- lastfm_close,
- lastfm_read,
lastfm_schemes,
nullptr,
diff --git a/src/playlist/M3uPlaylistPlugin.cxx b/src/playlist/M3uPlaylistPlugin.cxx
index d9f1e4737..8854be8d7 100644
--- a/src/playlist/M3uPlaylistPlugin.cxx
+++ b/src/playlist/M3uPlaylistPlugin.cxx
@@ -20,47 +20,37 @@
#include "config.h"
#include "M3uPlaylistPlugin.hxx"
#include "PlaylistPlugin.hxx"
+#include "SongEnumerator.hxx"
#include "Song.hxx"
#include "TextInputStream.hxx"
#include <glib.h>
-struct M3uPlaylist {
- struct playlist_provider base;
-
+class M3uPlaylist final : public SongEnumerator {
TextInputStream tis;
+public:
M3uPlaylist(input_stream *is)
:tis(is) {
- playlist_provider_init(&base, &m3u_playlist_plugin);
}
+
+ virtual Song *NextSong() override;
};
-static struct playlist_provider *
+static SongEnumerator *
m3u_open_stream(struct input_stream *is)
{
- M3uPlaylist *playlist = new M3uPlaylist(is);
-
- return &playlist->base;
-}
-
-static void
-m3u_close(struct playlist_provider *_playlist)
-{
- M3uPlaylist *playlist = (M3uPlaylist *)_playlist;
-
- delete playlist;
+ return new M3uPlaylist(is);
}
-static Song *
-m3u_read(struct playlist_provider *_playlist)
+Song *
+M3uPlaylist::NextSong()
{
- M3uPlaylist *playlist = (M3uPlaylist *)_playlist;
std::string line;
const char *line_s;
do {
- if (!playlist->tis.ReadLine(line))
+ if (!tis.ReadLine(line))
return NULL;
line_s = line.c_str();
@@ -89,8 +79,6 @@ const struct playlist_plugin m3u_playlist_plugin = {
nullptr,
nullptr,
m3u_open_stream,
- m3u_close,
- m3u_read,
nullptr,
m3u_suffixes,
diff --git a/src/playlist/PlsPlaylistPlugin.cxx b/src/playlist/PlsPlaylistPlugin.cxx
index 4a0fde45f..946fe9c55 100644
--- a/src/playlist/PlsPlaylistPlugin.cxx
+++ b/src/playlist/PlsPlaylistPlugin.cxx
@@ -19,7 +19,8 @@
#include "config.h"
#include "PlsPlaylistPlugin.hxx"
-#include "MemoryPlaylistProvider.hxx"
+#include "PlaylistPlugin.hxx"
+#include "MemorySongEnumerator.hxx"
#include "InputStream.hxx"
#include "Song.hxx"
#include "Tag.hxx"
@@ -101,7 +102,7 @@ pls_parser(GKeyFile *keyfile, std::forward_list<SongPointer> &songs)
}
-static struct playlist_provider *
+static SongEnumerator *
pls_open_stream(struct input_stream *is)
{
GError *error = NULL;
@@ -150,7 +151,7 @@ pls_open_stream(struct input_stream *is)
g_key_file_free(keyfile);
songs.reverse();
- return new MemoryPlaylistProvider(std::move(songs));
+ return new MemorySongEnumerator(std::move(songs));
}
static const char *const pls_suffixes[] = {
@@ -170,8 +171,6 @@ const struct playlist_plugin pls_playlist_plugin = {
nullptr,
nullptr,
pls_open_stream,
- nullptr,
- nullptr,
nullptr,
pls_suffixes,
diff --git a/src/playlist/RssPlaylistPlugin.cxx b/src/playlist/RssPlaylistPlugin.cxx
index c045b4df2..97c0d806b 100644
--- a/src/playlist/RssPlaylistPlugin.cxx
+++ b/src/playlist/RssPlaylistPlugin.cxx
@@ -19,7 +19,8 @@
#include "config.h"
#include "RssPlaylistPlugin.hxx"
-#include "MemoryPlaylistProvider.hxx"
+#include "PlaylistPlugin.hxx"
+#include "MemorySongEnumerator.hxx"
#include "InputStream.hxx"
#include "Song.hxx"
#include "Tag.hxx"
@@ -198,7 +199,7 @@ rss_parser_destroy(gpointer data)
*
*/
-static struct playlist_provider *
+static SongEnumerator *
rss_open_stream(struct input_stream *is)
{
RssParser parser;
@@ -246,8 +247,8 @@ rss_open_stream(struct input_stream *is)
}
parser.songs.reverse();
- MemoryPlaylistProvider *playlist =
- new MemoryPlaylistProvider(std::move(parser.songs));
+ MemorySongEnumerator *playlist =
+ new MemorySongEnumerator(std::move(parser.songs));
g_markup_parse_context_free(context);
@@ -272,8 +273,6 @@ const struct playlist_plugin rss_playlist_plugin = {
nullptr,
nullptr,
rss_open_stream,
- nullptr,
- nullptr,
nullptr,
rss_suffixes,
diff --git a/src/playlist/SoundCloudPlaylistPlugin.cxx b/src/playlist/SoundCloudPlaylistPlugin.cxx
index 5679062cf..f822382fc 100644
--- a/src/playlist/SoundCloudPlaylistPlugin.cxx
+++ b/src/playlist/SoundCloudPlaylistPlugin.cxx
@@ -19,7 +19,8 @@
#include "config.h"
#include "SoundCloudPlaylistPlugin.hxx"
-#include "MemoryPlaylistProvider.hxx"
+#include "PlaylistPlugin.hxx"
+#include "MemorySongEnumerator.hxx"
#include "ConfigData.hxx"
#include "InputStream.hxx"
#include "Song.hxx"
@@ -315,7 +316,7 @@ soundcloud_parse_json(const char *url, yajl_handle hand,
* soundcloud://url/<url or path of soundcloud page>
*/
-static struct playlist_provider *
+static SongEnumerator *
soundcloud_open_uri(const char *uri, Mutex &mutex, Cond &cond)
{
char *s, *p;
@@ -389,7 +390,7 @@ soundcloud_open_uri(const char *uri, Mutex &mutex, Cond &cond)
return NULL;
data.songs.reverse();
- return new MemoryPlaylistProvider(std::move(data.songs));
+ return new MemorySongEnumerator(std::move(data.songs));
}
static const char *const soundcloud_schemes[] = {
@@ -404,8 +405,6 @@ const struct playlist_plugin soundcloud_playlist_plugin = {
soundcloud_finish,
soundcloud_open_uri,
nullptr,
- nullptr,
- nullptr,
soundcloud_schemes,
nullptr,
diff --git a/src/playlist/XspfPlaylistPlugin.cxx b/src/playlist/XspfPlaylistPlugin.cxx
index 667f484b2..002a03f8a 100644
--- a/src/playlist/XspfPlaylistPlugin.cxx
+++ b/src/playlist/XspfPlaylistPlugin.cxx
@@ -19,7 +19,8 @@
#include "config.h"
#include "XspfPlaylistPlugin.hxx"
-#include "MemoryPlaylistProvider.hxx"
+#include "PlaylistPlugin.hxx"
+#include "MemorySongEnumerator.hxx"
#include "InputStream.hxx"
#include "Tag.hxx"
#include "util/Error.hxx"
@@ -217,7 +218,7 @@ xspf_parser_destroy(gpointer data)
*
*/
-static struct playlist_provider *
+static SongEnumerator *
xspf_open_stream(struct input_stream *is)
{
XspfParser parser;
@@ -265,8 +266,8 @@ xspf_open_stream(struct input_stream *is)
}
parser.songs.reverse();
- MemoryPlaylistProvider *playlist =
- new MemoryPlaylistProvider(std::move(parser.songs));
+ MemorySongEnumerator *playlist =
+ new MemorySongEnumerator(std::move(parser.songs));
g_markup_parse_context_free(context);
@@ -290,8 +291,6 @@ const struct playlist_plugin xspf_playlist_plugin = {
nullptr,
nullptr,
xspf_open_stream,
- nullptr,
- nullptr,
nullptr,
xspf_suffixes,
diff --git a/test/dump_playlist.cxx b/test/dump_playlist.cxx
index c42a2c52b..45719fab0 100644
--- a/test/dump_playlist.cxx
+++ b/test/dump_playlist.cxx
@@ -20,6 +20,7 @@
#include "config.h"
#include "TagSave.hxx"
#include "Song.hxx"
+#include "SongEnumerator.hxx"
#include "Directory.hxx"
#include "InputStream.hxx"
#include "ConfigGlobal.hxx"
@@ -141,7 +142,6 @@ int main(int argc, char **argv)
{
const char *uri;
struct input_stream *is = NULL;
- struct playlist_provider *playlist;
Song *song;
if (argc != 3) {
@@ -186,7 +186,7 @@ int main(int argc, char **argv)
Mutex mutex;
Cond cond;
- playlist = playlist_list_open_uri(uri, mutex, cond);
+ auto playlist = playlist_list_open_uri(uri, mutex, cond);
if (playlist == NULL) {
/* open the stream and wait until it becomes ready */
@@ -213,7 +213,7 @@ int main(int argc, char **argv)
/* dump the playlist */
- while ((song = playlist_plugin_read(playlist)) != NULL) {
+ while ((song = playlist->NextSong()) != NULL) {
g_print("%s\n", song->uri);
if (song->end_ms > 0)
@@ -235,7 +235,7 @@ int main(int argc, char **argv)
/* deinitialize everything */
- playlist_plugin_close(playlist);
+ delete playlist;
if (is != NULL)
is->Close();