summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/input/InputPlugin.cxx35
-rw-r--r--src/input/InputPlugin.hxx12
-rw-r--r--src/input/Open.cxx3
-rw-r--r--src/input/ScanTags.cxx2
-rw-r--r--src/input/meson.build1
-rw-r--r--src/input/plugins/AlsaInputPlugin.cxx6
-rw-r--r--src/input/plugins/CdioParanoiaInputPlugin.cxx6
-rw-r--r--src/input/plugins/CurlInputPlugin.cxx7
-rw-r--r--src/input/plugins/FfmpegInputPlugin.cxx19
-rw-r--r--src/input/plugins/MmsInputPlugin.cxx15
-rw-r--r--src/input/plugins/NfsInputPlugin.cxx9
-rw-r--r--src/input/plugins/QobuzInputPlugin.cxx6
-rw-r--r--src/input/plugins/SmbclientInputPlugin.cxx9
-rw-r--r--src/input/plugins/TidalInputPlugin.cxx6
-rw-r--r--src/ls.cxx78
-rw-r--r--src/ls.hxx2
16 files changed, 128 insertions, 88 deletions
diff --git a/src/input/InputPlugin.cxx b/src/input/InputPlugin.cxx
new file mode 100644
index 000000000..4175f8d93
--- /dev/null
+++ b/src/input/InputPlugin.cxx
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2003-2018 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 "InputPlugin.hxx"
+#include "util/StringCompare.hxx"
+
+#include <assert.h>
+
+bool
+InputPlugin::SupportsUri(const char *uri) const noexcept
+{
+ assert(prefixes != nullptr);
+
+ for (auto i = prefixes; *i != nullptr; ++i)
+ if (StringStartsWithIgnoreCase(uri, *i))
+ return true;
+
+ return false;
+}
diff --git a/src/input/InputPlugin.hxx b/src/input/InputPlugin.hxx
index 0a235f51a..51b44c061 100644
--- a/src/input/InputPlugin.hxx
+++ b/src/input/InputPlugin.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2017 The Music Player Daemon Project
+ * Copyright 2003-2018 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -21,6 +21,7 @@
#define MPD_INPUT_PLUGIN_HXX
#include "Ptr.hxx"
+#include "util/Compiler.h"
struct ConfigBlock;
class Mutex;
@@ -32,6 +33,12 @@ struct InputPlugin {
const char *name;
/**
+ * A nullptr-terminated list of URI prefixes handled by this
+ * plugin. This is usually a string in the form "scheme://".
+ */
+ const char *const*prefixes;
+
+ /**
* Global initialization. This method is called when MPD starts.
*
* Throws #PluginUnavailable if the plugin is not available
@@ -66,6 +73,9 @@ struct InputPlugin {
*/
std::unique_ptr<RemoteTagScanner> (*scan_tags)(const char *uri,
RemoteTagHandler &handler) = nullptr;
+
+ gcc_pure
+ bool SupportsUri(const char *uri) const noexcept;
};
#endif
diff --git a/src/input/Open.cxx b/src/input/Open.cxx
index 22400c142..e8f2aae09 100644
--- a/src/input/Open.cxx
+++ b/src/input/Open.cxx
@@ -38,6 +38,9 @@ InputStream::Open(const char *url, Mutex &mutex)
}
input_plugins_for_each_enabled(plugin) {
+ if (!plugin->SupportsUri(url))
+ continue;
+
auto is = plugin->open(url, mutex);
if (is != nullptr)
return input_rewind_open(std::move(is));
diff --git a/src/input/ScanTags.cxx b/src/input/ScanTags.cxx
index 64183097f..0781860a0 100644
--- a/src/input/ScanTags.cxx
+++ b/src/input/ScanTags.cxx
@@ -27,7 +27,7 @@ std::unique_ptr<RemoteTagScanner>
InputScanTags(const char *uri, RemoteTagHandler &handler)
{
input_plugins_for_each_enabled(plugin) {
- if (plugin->scan_tags == nullptr)
+ if (plugin->scan_tags == nullptr || !plugin->SupportsUri(uri))
continue;
auto scanner = plugin->scan_tags(uri, handler);
diff --git a/src/input/meson.build b/src/input/meson.build
index aa2720383..3c5e031b5 100644
--- a/src/input/meson.build
+++ b/src/input/meson.build
@@ -1,6 +1,7 @@
input_api = static_library(
'input_api',
'Error.cxx',
+ 'InputPlugin.cxx',
'InputStream.cxx',
'ThreadInputStream.cxx',
'AsyncInputStream.cxx',
diff --git a/src/input/plugins/AlsaInputPlugin.cxx b/src/input/plugins/AlsaInputPlugin.cxx
index f71261b1f..5484f18a8 100644
--- a/src/input/plugins/AlsaInputPlugin.cxx
+++ b/src/input/plugins/AlsaInputPlugin.cxx
@@ -409,8 +409,14 @@ alsa_input_open(const char *uri, Mutex &mutex)
mutex);
}
+static constexpr const char *alsa_prefixes[] = {
+ "alsa://",
+ nullptr
+};
+
const struct InputPlugin input_plugin_alsa = {
"alsa",
+ alsa_prefixes,
alsa_input_init,
nullptr,
alsa_input_open,
diff --git a/src/input/plugins/CdioParanoiaInputPlugin.cxx b/src/input/plugins/CdioParanoiaInputPlugin.cxx
index eeba659b8..90e0f1dae 100644
--- a/src/input/plugins/CdioParanoiaInputPlugin.cxx
+++ b/src/input/plugins/CdioParanoiaInputPlugin.cxx
@@ -357,8 +357,14 @@ CdioParanoiaInputStream::IsEOF() noexcept
return lsn_from + lsn_relofs > lsn_to;
}
+static constexpr const char *cdio_paranoia_prefixes[] = {
+ "cdda://",
+ nullptr
+};
+
const InputPlugin input_plugin_cdio_paranoia = {
"cdio_paranoia",
+ cdio_paranoia_prefixes,
input_cdio_init,
nullptr,
input_cdio_open,
diff --git a/src/input/plugins/CurlInputPlugin.cxx b/src/input/plugins/CurlInputPlugin.cxx
index bdbdcac61..2894833f3 100644
--- a/src/input/plugins/CurlInputPlugin.cxx
+++ b/src/input/plugins/CurlInputPlugin.cxx
@@ -473,8 +473,15 @@ input_curl_open(const char *url, Mutex &mutex)
return CurlInputStream::Open(url, {}, mutex);
}
+static constexpr const char *curl_prefixes[] = {
+ "http://",
+ "https://",
+ nullptr
+};
+
const struct InputPlugin input_plugin_curl = {
"curl",
+ curl_prefixes,
input_curl_init,
input_curl_finish,
input_curl_open,
diff --git a/src/input/plugins/FfmpegInputPlugin.cxx b/src/input/plugins/FfmpegInputPlugin.cxx
index 0f922650a..0c0b6c91e 100644
--- a/src/input/plugins/FfmpegInputPlugin.cxx
+++ b/src/input/plugins/FfmpegInputPlugin.cxx
@@ -85,14 +85,6 @@ static InputStreamPtr
input_ffmpeg_open(const char *uri,
Mutex &mutex)
{
- if (!StringStartsWithCaseASCII(uri, "gopher://") &&
- !StringStartsWithCaseASCII(uri, "rtp://") &&
- !StringStartsWithCaseASCII(uri, "rtsp://") &&
- !StringStartsWithCaseASCII(uri, "rtmp://") &&
- !StringStartsWithCaseASCII(uri, "rtmpt://") &&
- !StringStartsWithCaseASCII(uri, "rtmps://"))
- return nullptr;
-
AVIOContext *h;
auto result = avio_open(&h, uri, AVIO_FLAG_READ);
if (result != 0)
@@ -146,8 +138,19 @@ FfmpegInputStream::Seek(offset_type new_offset)
eof = false;
}
+static constexpr const char *ffmpeg_prefixes[] = {
+ "gopher://",
+ "rtp://",
+ "rtsp://",
+ "rtmp://",
+ "rtmpt://",
+ "rtmps://",
+ nullptr
+};
+
const InputPlugin input_plugin_ffmpeg = {
"ffmpeg",
+ ffmpeg_prefixes,
input_ffmpeg_init,
nullptr,
input_ffmpeg_open,
diff --git a/src/input/plugins/MmsInputPlugin.cxx b/src/input/plugins/MmsInputPlugin.cxx
index 9e600ee10..b7e752688 100644
--- a/src/input/plugins/MmsInputPlugin.cxx
+++ b/src/input/plugins/MmsInputPlugin.cxx
@@ -72,12 +72,6 @@ static InputStreamPtr
input_mms_open(const char *url,
Mutex &mutex)
{
- if (!StringStartsWithCaseASCII(url, "mms://") &&
- !StringStartsWithCaseASCII(url, "mmsh://") &&
- !StringStartsWithCaseASCII(url, "mmst://") &&
- !StringStartsWithCaseASCII(url, "mmsu://"))
- return nullptr;
-
auto m = std::make_unique<MmsInputStream>(url, mutex);
m->Start();
return m;
@@ -103,8 +97,17 @@ MmsInputStream::ThreadRead(void *ptr, size_t read_size)
return (size_t)nbytes;
}
+static constexpr const char *mms_prefixes[] = {
+ "mms://",
+ "mmsh://",
+ "mmst://",
+ "mmsu://",
+ nullptr
+};
+
const InputPlugin input_plugin_mms = {
"mms",
+ mms_prefixes,
nullptr,
nullptr,
input_mms_open,
diff --git a/src/input/plugins/NfsInputPlugin.cxx b/src/input/plugins/NfsInputPlugin.cxx
index 8544243c9..a0b9750e1 100644
--- a/src/input/plugins/NfsInputPlugin.cxx
+++ b/src/input/plugins/NfsInputPlugin.cxx
@@ -217,16 +217,19 @@ static InputStreamPtr
input_nfs_open(const char *uri,
Mutex &mutex)
{
- if (!StringStartsWithCaseASCII(uri, "nfs://"))
- return nullptr;
-
auto is = std::make_unique<NfsInputStream>(uri, mutex);
is->Open();
return is;
}
+static constexpr const char *nfs_prefixes[] = {
+ "nfs://",
+ nullptr
+};
+
const InputPlugin input_plugin_nfs = {
"nfs",
+ nfs_prefixes,
input_nfs_init,
input_nfs_finish,
input_nfs_open,
diff --git a/src/input/plugins/QobuzInputPlugin.cxx b/src/input/plugins/QobuzInputPlugin.cxx
index 29723b24a..d0717b345 100644
--- a/src/input/plugins/QobuzInputPlugin.cxx
+++ b/src/input/plugins/QobuzInputPlugin.cxx
@@ -209,8 +209,14 @@ ScanQobuzTags(const char *uri, RemoteTagHandler &handler)
handler);
}
+static constexpr const char *qobuz_prefixes[] = {
+ "qobuz://",
+ nullptr
+};
+
const InputPlugin qobuz_input_plugin = {
"qobuz",
+ qobuz_prefixes,
InitQobuzInput,
FinishQobuzInput,
OpenQobuzInput,
diff --git a/src/input/plugins/SmbclientInputPlugin.cxx b/src/input/plugins/SmbclientInputPlugin.cxx
index 84ac47cae..c4b9db264 100644
--- a/src/input/plugins/SmbclientInputPlugin.cxx
+++ b/src/input/plugins/SmbclientInputPlugin.cxx
@@ -87,9 +87,6 @@ static InputStreamPtr
input_smbclient_open(const char *uri,
Mutex &mutex)
{
- if (!StringStartsWithCaseASCII(uri, "smb://"))
- return nullptr;
-
const std::lock_guard<Mutex> protect(smbclient_mutex);
SMBCCTX *ctx = smbc_new_context();
@@ -158,8 +155,14 @@ SmbclientInputStream::Seek(offset_type new_offset)
offset = result;
}
+static constexpr const char *smbclient_prefixes[] = {
+ "smb://",
+ nullptr
+};
+
const InputPlugin input_plugin_smbclient = {
"smbclient",
+ smbclient_prefixes,
input_smbclient_init,
nullptr,
input_smbclient_open,
diff --git a/src/input/plugins/TidalInputPlugin.cxx b/src/input/plugins/TidalInputPlugin.cxx
index 9f28cdbda..a94e94af0 100644
--- a/src/input/plugins/TidalInputPlugin.cxx
+++ b/src/input/plugins/TidalInputPlugin.cxx
@@ -239,8 +239,14 @@ ScanTidalTags(const char *uri, RemoteTagHandler &handler)
track_id, handler);
}
+static constexpr const char *tidal_prefixes[] = {
+ "tidal://",
+ nullptr
+};
+
const InputPlugin tidal_input_plugin = {
"tidal",
+ tidal_prefixes,
InitTidalInput,
FinishTidalInput,
OpenTidalInput,
diff --git a/src/ls.cxx b/src/ls.cxx
index 7768510c7..8bc6330f4 100644
--- a/src/ls.cxx
+++ b/src/ls.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2017 The Music Player Daemon Project
+ * Copyright 2003-2018 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -19,94 +19,42 @@
#include "config.h"
#include "ls.hxx"
+#include "input/Registry.hxx"
+#include "input/InputPlugin.hxx"
#include "client/Response.hxx"
#include "util/ASCII.hxx"
#include "util/UriUtil.hxx"
#include <assert.h>
-/**
- * file:// is not included in remoteUrlPrefixes, the connection method
- * is detected at runtime and displayed as a urlhandler if the client is
- * connected by IPC socket.
- */
-static const char *const remoteUrlPrefixes[] = {
-#if defined(ENABLE_CURL)
- "http://",
- "https://",
-#endif
-#ifdef ENABLE_MMS
- "mms://",
- "mmsh://",
- "mmst://",
- "mmsu://",
-#endif
-#ifdef ENABLE_FFMPEG
- "gopher://",
- "rtp://",
- "rtsp://",
- "rtmp://",
- "rtmpt://",
- "rtmps://",
-#endif
-#ifdef ENABLE_SMBCLIENT
- "smb://",
-#endif
-#ifdef ENABLE_NFS
- "nfs://",
-#endif
-#ifdef ENABLE_CDIO_PARANOIA
- "cdda://",
-#endif
-#ifdef ENABLE_ALSA
- "alsa://",
-#endif
-#ifdef ENABLE_QOBUZ
- "qobuz://",
-#endif
-#ifdef ENABLE_TIDAL
- "tidal://",
-#endif
- NULL
-};
-
void print_supported_uri_schemes_to_fp(FILE *fp)
{
- const char *const*prefixes = remoteUrlPrefixes;
-
#ifdef HAVE_UN
fprintf(fp, " file://");
#endif
- while (*prefixes) {
- fprintf(fp, " %s", *prefixes);
- prefixes++;
- }
+ input_plugins_for_each(plugin)
+ for (auto i = plugin->prefixes; *i != nullptr; ++i)
+ fprintf(fp, " %s", *i);
fprintf(fp,"\n");
}
void
print_supported_uri_schemes(Response &r)
{
- const char *const *prefixes = remoteUrlPrefixes;
-
- while (*prefixes) {
- r.Format("handler: %s\n", *prefixes);
- prefixes++;
- }
+ input_plugins_for_each_enabled(plugin)
+ for (auto i = plugin->prefixes; *i != nullptr; ++i)
+ r.Format("handler: %s\n", *i);
}
bool
uri_supported_scheme(const char *uri) noexcept
{
- const char *const*urlPrefixes = remoteUrlPrefixes;
-
assert(uri_has_scheme(uri));
- while (*urlPrefixes) {
- if (StringStartsWithCaseASCII(uri, *urlPrefixes))
- return true;
- urlPrefixes++;
- }
+ input_plugins_for_each_enabled(plugin)
+ for (auto i = plugin->prefixes; *i != nullptr; ++i)
+ if (StringStartsWithCaseASCII(uri, *i))
+ return true;
return false;
}
diff --git a/src/ls.hxx b/src/ls.hxx
index aec5d8623..f9194f3e6 100644
--- a/src/ls.hxx
+++ b/src/ls.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2017 The Music Player Daemon Project
+ * Copyright 2003-2018 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify