aboutsummaryrefslogtreecommitdiffstats
path: root/src/command/QueueCommands.cxx
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-02-02 14:37:52 +0100
committerMax Kellermann <max@duempel.org>2014-02-03 23:32:10 +0100
commitca36ac2ba196ee2bbe4b54ee9a71d49174803277 (patch)
treed365b1ac7872e1785befdcebf254885c1c27a268 /src/command/QueueCommands.cxx
parentba675d6a55769a6e82a6efaa2f4a812a4eea2362 (diff)
downloadmpd-ca36ac2ba196ee2bbe4b54ee9a71d49174803277.tar.gz
mpd-ca36ac2ba196ee2bbe4b54ee9a71d49174803277.tar.xz
mpd-ca36ac2ba196ee2bbe4b54ee9a71d49174803277.zip
SongLoader: new class that merges duplicate code
There was quite a lot of duplicate code for loading DetachedSong objects, with different semantics for "securely" loading local files.
Diffstat (limited to 'src/command/QueueCommands.cxx')
-rw-r--r--src/command/QueueCommands.cxx85
1 files changed, 30 insertions, 55 deletions
diff --git a/src/command/QueueCommands.cxx b/src/command/QueueCommands.cxx
index 5bef1b461..f14beb872 100644
--- a/src/command/QueueCommands.cxx
+++ b/src/command/QueueCommands.cxx
@@ -21,8 +21,9 @@
#include "QueueCommands.hxx"
#include "CommandError.hxx"
#include "db/DatabaseQueue.hxx"
-#include "SongFilter.hxx"
#include "db/Selection.hxx"
+#include "SongFilter.hxx"
+#include "SongLoader.hxx"
#include "Playlist.hxx"
#include "PlaylistPrint.hxx"
#include "client/Client.hxx"
@@ -38,38 +39,32 @@
#include <string.h>
-CommandResult
-handle_add(Client &client, gcc_unused int argc, char *argv[])
+static const char *
+translate_uri(Client &client, const char *uri)
{
- char *uri = argv[1];
- PlaylistResult result;
-
- if (memcmp(uri, "file:///", 8) == 0) {
- const char *path_utf8 = uri + 7;
- const auto path_fs = AllocatedPath::FromUTF8(path_utf8);
-
- if (path_fs.IsNull()) {
- command_error(client, ACK_ERROR_NO_EXIST,
- "unsupported file name");
- return CommandResult::ERROR;
- }
-
- Error error;
- if (!client.AllowFile(path_fs, error))
- return print_error(client, error);
-
- result = client.partition.AppendFile(path_utf8);
- return print_playlist_result(client, result);
+ if (memcmp(uri, "file:///", 8) == 0)
+ /* drop the "file://", leave only an absolute path
+ (starting with a slash) */
+ return uri + 7;
+
+ if (PathTraitsUTF8::IsAbsolute(uri)) {
+ command_error(client, ACK_ERROR_NO_EXIST, "Malformed URI");
+ return nullptr;
}
- if (uri_has_scheme(uri)) {
- if (!uri_supported_scheme(uri)) {
- command_error(client, ACK_ERROR_NO_EXIST,
- "unsupported URI scheme");
- return CommandResult::ERROR;
- }
+ return uri;
+}
- result = client.partition.AppendURI(uri);
+CommandResult
+handle_add(Client &client, gcc_unused int argc, char *argv[])
+{
+ const char *const uri = translate_uri(client, argv[1]);
+ if (uri == nullptr)
+ return CommandResult::ERROR;
+
+ if (uri_has_scheme(uri) || PathTraitsUTF8::IsAbsolute(uri)) {
+ const SongLoader loader(client);
+ auto result = client.partition.AppendURI(loader, uri);
return print_playlist_result(client, result);
}
@@ -88,34 +83,14 @@ handle_add(Client &client, gcc_unused int argc, char *argv[])
CommandResult
handle_addid(Client &client, int argc, char *argv[])
{
- char *uri = argv[1];
- unsigned added_id;
- PlaylistResult result;
-
- if (memcmp(uri, "file:///", 8) == 0) {
- const char *path_utf8 = uri + 7;
- const auto path_fs = AllocatedPath::FromUTF8(path_utf8);
-
- if (path_fs.IsNull()) {
- command_error(client, ACK_ERROR_NO_EXIST,
- "unsupported file name");
- return CommandResult::ERROR;
- }
+ const char *const uri = translate_uri(client, argv[1]);
+ if (uri == nullptr)
+ return CommandResult::ERROR;
- Error error;
- if (!client.AllowFile(path_fs, error))
- return print_error(client, error);
+ const SongLoader loader(client);
- result = client.partition.AppendFile(path_utf8, &added_id);
- } else {
- if (uri_has_scheme(uri) && !uri_supported_scheme(uri)) {
- command_error(client, ACK_ERROR_NO_EXIST,
- "unsupported URI scheme");
- return CommandResult::ERROR;
- }
-
- result = client.partition.AppendURI(uri, &added_id);
- }
+ unsigned added_id;
+ auto result = client.partition.AppendURI(loader, uri, &added_id);
if (result != PlaylistResult::SUCCESS)
return print_playlist_result(client, result);