command/file: move code to TagScanAny()

This commit is contained in:
Max Kellermann 2019-08-12 19:24:24 +02:00
parent b717ab0383
commit 3895d35a52
4 changed files with 141 additions and 79 deletions

View File

@ -277,6 +277,7 @@ sources = [
'src/TagSave.cxx', 'src/TagSave.cxx',
'src/TagFile.cxx', 'src/TagFile.cxx',
'src/TagStream.cxx', 'src/TagStream.cxx',
'src/TagAny.cxx',
'src/TimePrint.cxx', 'src/TimePrint.cxx',
'src/mixer/Volume.cxx', 'src/mixer/Volume.cxx',
'src/PlaylistFile.cxx', 'src/PlaylistFile.cxx',

100
src/TagAny.cxx Normal file
View File

@ -0,0 +1,100 @@
/*
* Copyright 2003-2019 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 "TagAny.hxx"
#include "TagStream.hxx"
#include "TagFile.hxx"
#include "tag/Generic.hxx"
#include "storage/StorageInterface.hxx"
#include "client/Client.hxx"
#include "protocol/Ack.hxx"
#include "fs/AllocatedPath.hxx"
#include "util/Compiler.h"
#include "util/UriExtract.hxx"
#include "LocateUri.hxx"
static void
TagScanStream(const char *uri, TagHandler &handler)
{
if (!tag_stream_scan(uri, handler))
throw ProtocolError(ACK_ERROR_NO_EXIST, "Failed to load file");
}
static void
TagScanFile(const Path path_fs, TagHandler &handler)
{
if (!ScanFileTagsNoGeneric(path_fs, handler))
throw ProtocolError(ACK_ERROR_NO_EXIST, "Failed to load file");
ScanGenericTags(path_fs, handler);
}
static void
TagScanDatabase(Client &client, const char *uri, TagHandler &handler)
{
#ifdef ENABLE_DATABASE
const Storage *storage = client.GetStorage();
if (storage == nullptr) {
#else
(void)client;
(void)uri;
(void)handler;
#endif
throw ProtocolError(ACK_ERROR_NO_EXIST, "No database");
#ifdef ENABLE_DATABASE
}
{
const auto path_fs = storage->MapFS(uri);
if (!path_fs.IsNull())
return TagScanFile(path_fs, handler);
}
{
const auto absolute_uri = storage->MapUTF8(uri);
if (uri_has_scheme(absolute_uri.c_str()))
return TagScanStream(absolute_uri.c_str(), handler);
}
throw ProtocolError(ACK_ERROR_NO_EXIST, "No such file");
#endif
}
void
TagScanAny(Client &client, const char *uri, TagHandler &handler)
{
const auto located_uri = LocateUri(UriPluginKind::INPUT, uri, &client
#ifdef ENABLE_DATABASE
, nullptr
#endif
);
switch (located_uri.type) {
case LocatedUri::Type::ABSOLUTE:
return TagScanStream(located_uri.canonical_uri, handler);
case LocatedUri::Type::RELATIVE:
return TagScanDatabase(client, located_uri.canonical_uri,
handler);
case LocatedUri::Type::PATH:
return TagScanFile(located_uri.path, handler);
}
gcc_unreachable();
}

36
src/TagAny.hxx Normal file
View File

@ -0,0 +1,36 @@
/*
* Copyright 2003-2019 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_TAG_ANY_HXX
#define MPD_TAG_ANY_HXX
class Client;
class TagHandler;
/**
* Scan tags in the song file specified by the given URI. The URI may
* be relative to the music directory (the "client" parameter will be
* used to obtain a handle to the #Storage) or absolute.
*
* Throws on error.
*/
void
TagScanAny(Client &client, const char *uri, TagHandler &handler);
#endif

View File

@ -30,8 +30,7 @@
#include "util/UriExtract.hxx" #include "util/UriExtract.hxx"
#include "tag/Handler.hxx" #include "tag/Handler.hxx"
#include "tag/Generic.hxx" #include "tag/Generic.hxx"
#include "TagStream.hxx" #include "TagAny.hxx"
#include "TagFile.hxx"
#include "storage/StorageInterface.hxx" #include "storage/StorageInterface.hxx"
#include "fs/AllocatedPath.hxx" #include "fs/AllocatedPath.hxx"
#include "fs/FileInfo.hxx" #include "fs/FileInfo.hxx"
@ -150,66 +149,6 @@ public:
} }
}; };
static CommandResult
read_stream_comments(Response &r, const char *uri)
{
PrintCommentHandler h(r);
if (!tag_stream_scan(uri, h)) {
r.Error(ACK_ERROR_NO_EXIST, "Failed to load file");
return CommandResult::ERROR;
}
return CommandResult::OK;
}
static CommandResult
read_file_comments(Response &r, const Path path_fs)
{
PrintCommentHandler h(r);
if (!ScanFileTagsNoGeneric(path_fs, h)) {
r.Error(ACK_ERROR_NO_EXIST, "Failed to load file");
return CommandResult::ERROR;
}
ScanGenericTags(path_fs, h);
return CommandResult::OK;
}
static CommandResult
read_db_comments(Client &client, Response &r, const char *uri)
{
#ifdef ENABLE_DATABASE
const Storage *storage = client.GetStorage();
if (storage == nullptr) {
#else
(void)client;
(void)uri;
#endif
r.Error(ACK_ERROR_NO_EXIST, "No database");
return CommandResult::ERROR;
#ifdef ENABLE_DATABASE
}
{
AllocatedPath path_fs = storage->MapFS(uri);
if (!path_fs.IsNull())
return read_file_comments(r, path_fs);
}
{
const std::string uri2 = storage->MapUTF8(uri);
if (uri_has_scheme(uri2.c_str()))
return read_stream_comments(r, uri2.c_str());
}
r.Error(ACK_ERROR_NO_EXIST, "No such file");
return CommandResult::ERROR;
#endif
}
CommandResult CommandResult
handle_read_comments(Client &client, Request args, Response &r) handle_read_comments(Client &client, Request args, Response &r)
{ {
@ -217,23 +156,9 @@ handle_read_comments(Client &client, Request args, Response &r)
const char *const uri = args.front(); const char *const uri = args.front();
const auto located_uri = LocateUri(UriPluginKind::INPUT, uri, &client PrintCommentHandler handler(r);
#ifdef ENABLE_DATABASE TagScanAny(client, uri, handler);
, nullptr return CommandResult::OK;
#endif
);
switch (located_uri.type) {
case LocatedUri::Type::ABSOLUTE:
return read_stream_comments(r, located_uri.canonical_uri);
case LocatedUri::Type::RELATIVE:
return read_db_comments(client, r, located_uri.canonical_uri);
case LocatedUri::Type::PATH:
return read_file_comments(r, located_uri.path);
}
gcc_unreachable();
} }
/** /**