diff options
author | Max Kellermann <max@duempel.org> | 2014-02-02 14:37:52 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2014-02-03 23:32:10 +0100 |
commit | ca36ac2ba196ee2bbe4b54ee9a71d49174803277 (patch) | |
tree | d365b1ac7872e1785befdcebf254885c1c27a268 /src/command/QueueCommands.cxx | |
parent | ba675d6a55769a6e82a6efaa2f4a812a4eea2362 (diff) | |
download | mpd-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.cxx | 85 |
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); |