diff options
author | Max Kellermann <max@musicpd.org> | 2017-02-07 16:52:59 +0100 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2017-02-08 09:06:11 +0100 |
commit | 29453ba196db55816ee10fa9908c3e3fa0acd40f (patch) | |
tree | 894470833ed3f549a6ab4458a734ba8657c771c4 /src | |
parent | 599d77643b57246dc877a2bbf65b932575fbf2c7 (diff) |
client: add tag_mask attribute
The "tagtypes" command now has several sub commands which can be used
to edit that mask.
Diffstat (limited to 'src')
-rw-r--r-- | src/TagPrint.cxx | 4 | ||||
-rw-r--r-- | src/client/Client.hxx | 6 | ||||
-rw-r--r-- | src/client/Response.cxx | 6 | ||||
-rw-r--r-- | src/client/Response.hxx | 9 | ||||
-rw-r--r-- | src/command/AllCommands.cxx | 2 | ||||
-rw-r--r-- | src/command/ClientCommands.cxx | 58 | ||||
-rw-r--r-- | src/command/OtherCommands.cxx | 3 | ||||
-rw-r--r-- | src/db/DatabasePrint.cxx | 3 |
8 files changed, 83 insertions, 8 deletions
diff --git a/src/TagPrint.cxx b/src/TagPrint.cxx index 1406f669b..61d86a12e 100644 --- a/src/TagPrint.cxx +++ b/src/TagPrint.cxx @@ -40,8 +40,10 @@ tag_print(Response &r, TagType type, const char *value) void tag_print_values(Response &r, const Tag &tag) { + const auto tag_mask = r.GetTagMask(); for (const auto &i : tag) - tag_print(r, i.type, i.value); + if (tag_mask.Test(i.type)) + tag_print(r, i.type, i.value); } void diff --git a/src/client/Client.hxx b/src/client/Client.hxx index 759e611d9..7ce128ce3 100644 --- a/src/client/Client.hxx +++ b/src/client/Client.hxx @@ -23,6 +23,7 @@ #include "check.h" #include "ClientMessage.hxx" #include "command/CommandListBuilder.hxx" +#include "tag/Mask.hxx" #include "event/FullyBufferedSocket.hxx" #include "event/TimeoutMonitor.hxx" #include "Compiler.h" @@ -71,6 +72,11 @@ public: unsigned idle_subscriptions; /** + * The tags this client is interested in. + */ + TagMask tag_mask = TagMask::All(); + + /** * A list of channel names this client is subscribed to. */ std::set<std::string> subscriptions; diff --git a/src/client/Response.cxx b/src/client/Response.cxx index 31eb6a78e..b21ac91b5 100644 --- a/src/client/Response.cxx +++ b/src/client/Response.cxx @@ -23,6 +23,12 @@ #include "util/FormatString.hxx" #include "util/AllocatedString.hxx" +TagMask +Response::GetTagMask() const +{ + return GetClient().tag_mask; +} + bool Response::Write(const void *data, size_t length) { diff --git a/src/client/Response.hxx b/src/client/Response.hxx index 280dc1d55..a133e96a3 100644 --- a/src/client/Response.hxx +++ b/src/client/Response.hxx @@ -22,11 +22,13 @@ #include "check.h" #include "protocol/Ack.hxx" +#include "Compiler.h" #include <stddef.h> #include <stdarg.h> class Client; +class TagMask; class Response { Client &client; @@ -59,6 +61,13 @@ public: return client; } + /** + * Accessor for Client::tag_mask. Can be used if caller wants + * to avoid including Client.hxx. + */ + gcc_pure + TagMask GetTagMask() const; + void SetCommand(const char *_command) { command = _command; } diff --git a/src/command/AllCommands.cxx b/src/command/AllCommands.cxx index 7d65898dd..45aed51ad 100644 --- a/src/command/AllCommands.cxx +++ b/src/command/AllCommands.cxx @@ -187,7 +187,7 @@ static constexpr struct command commands[] = { { "subscribe", PERMISSION_READ, 1, 1, handle_subscribe }, { "swap", PERMISSION_CONTROL, 2, 2, handle_swap }, { "swapid", PERMISSION_CONTROL, 2, 2, handle_swapid }, - { "tagtypes", PERMISSION_READ, 0, 0, handle_tagtypes }, + { "tagtypes", PERMISSION_READ, 0, -1, handle_tagtypes }, { "toggleoutput", PERMISSION_ADMIN, 1, 1, handle_toggleoutput }, #ifdef ENABLE_DATABASE { "unmount", PERMISSION_ADMIN, 1, 1, handle_unmount }, diff --git a/src/command/ClientCommands.cxx b/src/command/ClientCommands.cxx index 3aa89b0e6..c5f70b94d 100644 --- a/src/command/ClientCommands.cxx +++ b/src/command/ClientCommands.cxx @@ -24,6 +24,8 @@ #include "client/Client.hxx" #include "client/Response.hxx" #include "TagPrint.hxx" +#include "tag/ParseName.hxx" +#include "util/StringAPI.hxx" CommandResult handle_close(gcc_unused Client &client, gcc_unused Request args, @@ -53,10 +55,58 @@ handle_password(Client &client, Request args, Response &r) return CommandResult::OK; } +static TagMask +ParseTagMask(Request request) +{ + if (request.IsEmpty()) + throw ProtocolError(ACK_ERROR_ARG, "Not enough arguments"); + + TagMask result = TagMask::None(); + + for (const char *name : request) { + auto type = tag_name_parse_i(name); + if (type == TAG_NUM_OF_ITEM_TYPES) + throw ProtocolError(ACK_ERROR_ARG, "Unknown tag type"); + + result |= type; + } + + return result; +} + CommandResult -handle_tagtypes(gcc_unused Client &client, gcc_unused Request request, - Response &r) +handle_tagtypes(Client &client, Request request, Response &r) { - tag_print_types(r); - return CommandResult::OK; + if (request.IsEmpty()) { + tag_print_types(r); + return CommandResult::OK; + } + + const char *cmd = request.shift(); + if (StringIsEqual(cmd, "all")) { + if (!request.IsEmpty()) { + r.Error(ACK_ERROR_ARG, "Too many arguments"); + return CommandResult::ERROR; + } + + client.tag_mask = TagMask::All(); + return CommandResult::OK; + } else if (StringIsEqual(cmd, "clear")) { + if (!request.IsEmpty()) { + r.Error(ACK_ERROR_ARG, "Too many arguments"); + return CommandResult::ERROR; + } + + client.tag_mask = TagMask::None(); + return CommandResult::OK; + } else if (StringIsEqual(cmd, "enable")) { + client.tag_mask |= ParseTagMask(request); + return CommandResult::OK; + } else if (StringIsEqual(cmd, "disable")) { + client.tag_mask &= ~ParseTagMask(request); + return CommandResult::OK; + } else { + r.Error(ACK_ERROR_ARG, "Unknown sub command"); + return CommandResult::ERROR; + } } diff --git a/src/command/OtherCommands.cxx b/src/command/OtherCommands.cxx index 48487fe8e..013d4dff2 100644 --- a/src/command/OtherCommands.cxx +++ b/src/command/OtherCommands.cxx @@ -97,7 +97,8 @@ print_tag(TagType type, const char *value, void *ctx) { auto &r = *(Response *)ctx; - tag_print(r, type, value); + if (r.GetClient().tag_mask.Test(type)) + tag_print(r, type, value); } CommandResult diff --git a/src/db/DatabasePrint.cxx b/src/db/DatabasePrint.cxx index b5e0b69f7..31f971cd8 100644 --- a/src/db/DatabasePrint.cxx +++ b/src/db/DatabasePrint.cxx @@ -196,8 +196,9 @@ PrintUniqueTag(Response &r, TagType tag_type, assert(value != nullptr); tag_print(r, tag_type, value); + const auto tag_mask = r.GetTagMask(); for (const auto &item : tag) - if (item.type != tag_type) + if (item.type != tag_type && tag_mask.Test(item.type)) tag_print(r, item.type, item.value); } |