command/*: use std::span instead of ConstBuffer
This commit is contained in:
parent
baff5e5594
commit
9b427b3171
@ -337,17 +337,17 @@ command_check_request(const struct command *cmd, Response &r,
|
||||
if (min < 0)
|
||||
return true;
|
||||
|
||||
if (min == max && unsigned(max) != args.size) {
|
||||
if (min == max && unsigned(max) != args.size()) {
|
||||
r.FmtError(ACK_ERROR_ARG,
|
||||
FMT_STRING("wrong number of arguments for \"{}\""),
|
||||
cmd->cmd);
|
||||
return false;
|
||||
} else if (args.size < unsigned(min)) {
|
||||
} else if (args.size() < unsigned(min)) {
|
||||
r.FmtError(ACK_ERROR_ARG,
|
||||
FMT_STRING("too few arguments for \"{}\""),
|
||||
cmd->cmd);
|
||||
return false;
|
||||
} else if (max >= 0 && args.size > unsigned(max)) {
|
||||
} else if (max >= 0 && args.size() > unsigned(max)) {
|
||||
r.FmtError(ACK_ERROR_ARG,
|
||||
FMT_STRING("too many arguments for \"{}\""),
|
||||
cmd->cmd);
|
||||
@ -403,13 +403,13 @@ command_process(Client &client, unsigned num, char *line) noexcept
|
||||
}
|
||||
|
||||
char *argv[COMMAND_ARGV_MAX];
|
||||
Request args(argv, 0);
|
||||
|
||||
try {
|
||||
/* now parse the arguments (quoted or unquoted) */
|
||||
|
||||
std::size_t n_args = 0;
|
||||
while (true) {
|
||||
if (args.size == COMMAND_ARGV_MAX) {
|
||||
if (n_args == COMMAND_ARGV_MAX) {
|
||||
r.Error(ACK_ERROR_ARG, "Too many arguments");
|
||||
return CommandResult::ERROR;
|
||||
}
|
||||
@ -418,9 +418,11 @@ command_process(Client &client, unsigned num, char *line) noexcept
|
||||
if (a == nullptr)
|
||||
break;
|
||||
|
||||
argv[args.size++] = a;
|
||||
argv[n_args++] = a;
|
||||
}
|
||||
|
||||
Request args{argv, n_args};
|
||||
|
||||
/* look up and invoke the command handler */
|
||||
|
||||
const struct command *cmd =
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "client/Client.hxx"
|
||||
#include "client/Response.hxx"
|
||||
#include "tag/ParseName.hxx"
|
||||
#include "util/ConstBuffer.hxx"
|
||||
#include "util/Exception.hxx"
|
||||
#include "util/StringAPI.hxx"
|
||||
#include "util/ASCII.hxx"
|
||||
@ -75,8 +74,8 @@ ParseSortTag(const char *s)
|
||||
static unsigned
|
||||
ParseQueuePosition(Request &args, unsigned queue_length)
|
||||
{
|
||||
if (args.size >= 2 && StringIsEqual(args[args.size - 2], "position")) {
|
||||
unsigned position = args.ParseUnsigned(args.size - 1,
|
||||
if (args.size() >= 2 && StringIsEqual(args[args.size() - 2], "position")) {
|
||||
unsigned position = args.ParseUnsigned(args.size() - 1,
|
||||
queue_length);
|
||||
args.pop_back();
|
||||
args.pop_back();
|
||||
@ -90,7 +89,7 @@ ParseQueuePosition(Request &args, unsigned queue_length)
|
||||
static unsigned
|
||||
ParseInsertPosition(Request &args, const playlist &playlist)
|
||||
{
|
||||
if (args.size >= 2 && StringIsEqual(args[args.size - 2], "position")) {
|
||||
if (args.size() >= 2 && StringIsEqual(args[args.size() - 2], "position")) {
|
||||
unsigned position = ParseInsertPosition(args.back(), playlist);
|
||||
args.pop_back();
|
||||
args.pop_back();
|
||||
@ -110,8 +109,8 @@ static DatabaseSelection
|
||||
ParseDatabaseSelection(Request args, bool fold_case, SongFilter &filter)
|
||||
{
|
||||
RangeArg window = RangeArg::All();
|
||||
if (args.size >= 2 && StringIsEqual(args[args.size - 2], "window")) {
|
||||
window = args.ParseRange(args.size - 1);
|
||||
if (args.size() >= 2 && StringIsEqual(args[args.size() - 2], "window")) {
|
||||
window = args.ParseRange(args.size() - 1);
|
||||
|
||||
args.pop_back();
|
||||
args.pop_back();
|
||||
@ -119,7 +118,7 @@ ParseDatabaseSelection(Request args, bool fold_case, SongFilter &filter)
|
||||
|
||||
TagType sort = TAG_NUM_OF_ITEM_TYPES;
|
||||
bool descending = false;
|
||||
if (args.size >= 2 && StringIsEqual(args[args.size - 2], "sort")) {
|
||||
if (args.size() >= 2 && StringIsEqual(args[args.size() - 2], "sort")) {
|
||||
const char *s = args.back();
|
||||
if (*s == '-') {
|
||||
descending = true;
|
||||
@ -236,8 +235,8 @@ CommandResult
|
||||
handle_count(Client &client, Request args, Response &r)
|
||||
{
|
||||
TagType group = TAG_NUM_OF_ITEM_TYPES;
|
||||
if (args.size >= 2 && StringIsEqual(args[args.size - 2], "group")) {
|
||||
const char *s = args[args.size - 1];
|
||||
if (args.size() >= 2 && StringIsEqual(args[args.size() - 2], "group")) {
|
||||
const char *s = args[args.size() - 1];
|
||||
group = tag_name_parse_i(s);
|
||||
if (group == TAG_NUM_OF_ITEM_TYPES) {
|
||||
r.FmtError(ACK_ERROR_ARG,
|
||||
@ -317,7 +316,7 @@ handle_list(Client &client, Request args, Response &r)
|
||||
std::unique_ptr<SongFilter> filter;
|
||||
std::vector<TagType> tag_types;
|
||||
|
||||
if (args.size == 1 &&
|
||||
if (args.size() == 1 &&
|
||||
/* parantheses are the syntax for filter expressions: no
|
||||
compatibility mode */
|
||||
args.front()[0] != '(') {
|
||||
@ -333,9 +332,9 @@ handle_list(Client &client, Request args, Response &r)
|
||||
args.shift());
|
||||
}
|
||||
|
||||
while (args.size >= 2 &&
|
||||
StringIsEqual(args[args.size - 2], "group")) {
|
||||
const char *s = args[args.size - 1];
|
||||
while (args.size() >= 2 &&
|
||||
StringIsEqual(args[args.size() - 2], "group")) {
|
||||
const char *s = args[args.size() - 1];
|
||||
const auto group = tag_name_parse_i(s);
|
||||
if (group == TAG_NUM_OF_ITEM_TYPES) {
|
||||
r.FmtError(ACK_ERROR_ARG,
|
||||
|
@ -138,7 +138,7 @@ public:
|
||||
CommandResult
|
||||
handle_read_comments(Client &client, Request args, Response &r)
|
||||
{
|
||||
assert(args.size == 1);
|
||||
assert(args.size() == 1);
|
||||
|
||||
const char *const uri = args.front();
|
||||
|
||||
@ -288,7 +288,7 @@ read_db_art(Client &client, Response &r, const char *uri, const uint64_t offset)
|
||||
CommandResult
|
||||
handle_album_art(Client &client, Request args, Response &r)
|
||||
{
|
||||
assert(args.size == 2);
|
||||
assert(args.size() == 2);
|
||||
|
||||
const char *uri = args.front();
|
||||
size_t offset = args.ParseUnsigned(1);
|
||||
@ -368,7 +368,7 @@ public:
|
||||
CommandResult
|
||||
handle_read_picture(Client &client, Request args, Response &r)
|
||||
{
|
||||
assert(args.size == 2);
|
||||
assert(args.size() == 2);
|
||||
|
||||
const char *const uri = args.front();
|
||||
const size_t offset = args.ParseUnsigned(1);
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "client/Client.hxx"
|
||||
#include "client/List.hxx"
|
||||
#include "client/Response.hxx"
|
||||
#include "util/ConstBuffer.hxx"
|
||||
#include "Partition.hxx"
|
||||
|
||||
#include <fmt/format.h>
|
||||
@ -34,7 +33,7 @@
|
||||
CommandResult
|
||||
handle_subscribe(Client &client, Request args, Response &r)
|
||||
{
|
||||
assert(args.size == 1);
|
||||
assert(args.size() == 1);
|
||||
const char *const channel_name = args[0];
|
||||
|
||||
switch (client.Subscribe(channel_name)) {
|
||||
@ -62,7 +61,7 @@ handle_subscribe(Client &client, Request args, Response &r)
|
||||
CommandResult
|
||||
handle_unsubscribe(Client &client, Request args, Response &r)
|
||||
{
|
||||
assert(args.size == 1);
|
||||
assert(args.size() == 1);
|
||||
const char *const channel_name = args[0];
|
||||
|
||||
if (client.Unsubscribe(channel_name))
|
||||
@ -109,7 +108,7 @@ handle_read_messages(Client &client,
|
||||
CommandResult
|
||||
handle_send_message(Client &client, Request args, Response &r)
|
||||
{
|
||||
assert(args.size == 2);
|
||||
assert(args.size() == 2);
|
||||
|
||||
const char *const channel_name = args[0];
|
||||
const char *const message_text = args[1];
|
||||
|
@ -277,7 +277,7 @@ handle_update(Client &client, Request args, Response &r, bool discard)
|
||||
#ifdef ENABLE_DATABASE
|
||||
const char *path = "";
|
||||
|
||||
assert(args.size <= 1);
|
||||
assert(args.size() <= 1);
|
||||
if (!args.empty()) {
|
||||
path = args.front();
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
CommandResult
|
||||
handle_enableoutput(Client &client, Request args, Response &r)
|
||||
{
|
||||
assert(args.size == 1);
|
||||
assert(args.size() == 1);
|
||||
unsigned device = args.ParseUnsigned(0);
|
||||
|
||||
if (!audio_output_enable_index(client.GetPartition().outputs, device)) {
|
||||
@ -44,7 +44,7 @@ handle_enableoutput(Client &client, Request args, Response &r)
|
||||
CommandResult
|
||||
handle_disableoutput(Client &client, Request args, Response &r)
|
||||
{
|
||||
assert(args.size == 1);
|
||||
assert(args.size() == 1);
|
||||
unsigned device = args.ParseUnsigned(0);
|
||||
|
||||
if (!audio_output_disable_index(client.GetPartition().outputs, device)) {
|
||||
@ -58,7 +58,7 @@ handle_disableoutput(Client &client, Request args, Response &r)
|
||||
CommandResult
|
||||
handle_toggleoutput(Client &client, Request args, Response &r)
|
||||
{
|
||||
assert(args.size == 1);
|
||||
assert(args.size() == 1);
|
||||
unsigned device = args.ParseUnsigned(0);
|
||||
|
||||
if (!audio_output_toggle_index(client.GetPartition().outputs, device)) {
|
||||
@ -90,7 +90,7 @@ IsValidAttributeName(const char *s) noexcept
|
||||
CommandResult
|
||||
handle_outputset(Client &client, Request request, Response &response)
|
||||
{
|
||||
assert(request.size == 3);
|
||||
assert(request.size() == 3);
|
||||
const unsigned i = request.ParseUnsigned(0);
|
||||
|
||||
auto &partition = client.GetPartition();
|
||||
|
@ -41,7 +41,6 @@
|
||||
#include "Mapper.hxx"
|
||||
#include "fs/AllocatedPath.hxx"
|
||||
#include "time/ChronoUtil.hxx"
|
||||
#include "util/ConstBuffer.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
#include "LocateUri.hxx"
|
||||
|
||||
@ -88,7 +87,7 @@ handle_load(Client &client, Request args, [[maybe_unused]] Response &r)
|
||||
auto &playlist = client.GetPlaylist();
|
||||
const unsigned old_size = playlist.GetLength();
|
||||
|
||||
const unsigned position = args.size > 2
|
||||
const unsigned position = args.size() > 2
|
||||
? ParseInsertPosition(args[2], partition.playlist)
|
||||
: old_size;
|
||||
|
||||
@ -257,7 +256,7 @@ handle_playlistadd(Client &client, Request args, [[maybe_unused]] Response &r)
|
||||
const char *const playlist = args[0];
|
||||
const char *const uri = args[1];
|
||||
|
||||
if (args.size >= 3)
|
||||
if (args.size() >= 3)
|
||||
return handle_playlistadd_position(client, playlist, uri,
|
||||
args.ParseUnsigned(2), r);
|
||||
|
||||
|
@ -37,7 +37,6 @@
|
||||
#include "Partition.hxx"
|
||||
#include "Instance.hxx"
|
||||
#include "BulkEdit.hxx"
|
||||
#include "util/ConstBuffer.hxx"
|
||||
#include "util/Exception.hxx"
|
||||
#include "util/StringAPI.hxx"
|
||||
#include "util/NumberParser.hxx"
|
||||
@ -82,7 +81,7 @@ handle_add(Client &client, Request args, [[maybe_unused]] Response &r)
|
||||
uri = "";
|
||||
|
||||
const auto old_size = partition.playlist.GetLength();
|
||||
const unsigned position = args.size > 1
|
||||
const unsigned position = args.size() > 1
|
||||
? ParseInsertPosition(args[1], partition.playlist)
|
||||
: old_size;
|
||||
|
||||
@ -137,7 +136,7 @@ handle_addid(Client &client, Request args, Response &r)
|
||||
|
||||
const auto queue_length = partition.playlist.queue.GetLength();
|
||||
|
||||
if (args.size > 1)
|
||||
if (args.size() > 1)
|
||||
to = ParseInsertPosition(args[1], partition.playlist);
|
||||
|
||||
const SongLoader loader(client);
|
||||
@ -308,8 +307,8 @@ handle_playlist_match(Client &client, Request args, Response &r,
|
||||
bool fold_case)
|
||||
{
|
||||
RangeArg window = RangeArg::All();
|
||||
if (args.size >= 2 && StringIsEqual(args[args.size - 2], "window")) {
|
||||
window = args.ParseRange(args.size - 1);
|
||||
if (args.size() >= 2 && StringIsEqual(args[args.size() - 2], "window")) {
|
||||
window = args.ParseRange(args.size() - 1);
|
||||
|
||||
args.pop_back();
|
||||
args.pop_back();
|
||||
@ -317,7 +316,7 @@ handle_playlist_match(Client &client, Request args, Response &r,
|
||||
|
||||
TagType sort = TAG_NUM_OF_ITEM_TYPES;
|
||||
bool descending = false;
|
||||
if (args.size >= 2 && StringIsEqual(args[args.size - 2], "sort")) {
|
||||
if (args.size() >= 2 && StringIsEqual(args[args.size() - 2], "sort")) {
|
||||
const char *s = args.back();
|
||||
if (*s == '-') {
|
||||
descending = true;
|
||||
|
@ -23,80 +23,124 @@
|
||||
#include "protocol/ArgParser.hxx"
|
||||
#include "protocol/RangeArg.hxx"
|
||||
#include "Chrono.hxx"
|
||||
#include "util/ConstBuffer.hxx"
|
||||
|
||||
#include <cassert>
|
||||
#include <span>
|
||||
#include <utility>
|
||||
|
||||
class Response;
|
||||
|
||||
class Request : public ConstBuffer<const char *> {
|
||||
typedef ConstBuffer<const char *> Base;
|
||||
class Request {
|
||||
std::span<const char *const> args;
|
||||
|
||||
public:
|
||||
constexpr Request(const char *const*argv, size_type n)
|
||||
:Base(argv, n) {}
|
||||
explicit constexpr Request(const char *const*argv, std::size_t n)
|
||||
:args(argv, n) {}
|
||||
|
||||
constexpr bool empty() const noexcept {
|
||||
return args.empty();
|
||||
}
|
||||
|
||||
constexpr std::size_t size() const noexcept {
|
||||
return args.size();
|
||||
}
|
||||
|
||||
constexpr const char *front() const noexcept {
|
||||
return args.front();
|
||||
}
|
||||
|
||||
constexpr const char *back() const noexcept {
|
||||
return args.back();
|
||||
}
|
||||
|
||||
constexpr const char *shift() noexcept {
|
||||
const char *value = args.front();
|
||||
args = args.subspan(1);
|
||||
return value;
|
||||
}
|
||||
|
||||
constexpr const char *pop_back() noexcept {
|
||||
const char *value = args.back();
|
||||
args = args.first(args.size() - 1);
|
||||
return value;
|
||||
}
|
||||
|
||||
constexpr const char *operator[](std::size_t i) const noexcept {
|
||||
return args[i];
|
||||
}
|
||||
|
||||
constexpr auto begin() const noexcept {
|
||||
return args.begin();
|
||||
}
|
||||
|
||||
constexpr auto end() const noexcept {
|
||||
return args.end();
|
||||
}
|
||||
|
||||
constexpr operator std::span<const char *const>() const noexcept {
|
||||
return args;
|
||||
}
|
||||
|
||||
constexpr const char *GetOptional(unsigned idx,
|
||||
const char *default_value=nullptr) const {
|
||||
return idx < size
|
||||
? data[idx]
|
||||
return idx < size()
|
||||
? args[idx]
|
||||
: default_value;
|
||||
}
|
||||
|
||||
int ParseInt(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgInt(data[idx]);
|
||||
assert(idx < size());
|
||||
return ParseCommandArgInt(args[idx]);
|
||||
}
|
||||
|
||||
int ParseInt(unsigned idx, int min_value, int max_value) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgInt(data[idx], min_value, max_value);
|
||||
assert(idx < size());
|
||||
return ParseCommandArgInt(args[idx], min_value, max_value);
|
||||
}
|
||||
|
||||
unsigned ParseUnsigned(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgUnsigned(data[idx]);
|
||||
assert(idx < size());
|
||||
return ParseCommandArgUnsigned(args[idx]);
|
||||
}
|
||||
|
||||
unsigned ParseUnsigned(unsigned idx, unsigned max_value) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgUnsigned(data[idx], max_value);
|
||||
assert(idx < size());
|
||||
return ParseCommandArgUnsigned(args[idx], max_value);
|
||||
}
|
||||
|
||||
bool ParseBool(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgBool(data[idx]);
|
||||
assert(idx < size());
|
||||
return ParseCommandArgBool(args[idx]);
|
||||
}
|
||||
|
||||
RangeArg ParseRange(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgRange(data[idx]);
|
||||
assert(idx < size());
|
||||
return ParseCommandArgRange(args[idx]);
|
||||
}
|
||||
|
||||
float ParseFloat(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgFloat(data[idx]);
|
||||
assert(idx < size());
|
||||
return ParseCommandArgFloat(args[idx]);
|
||||
}
|
||||
|
||||
SongTime ParseSongTime(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgSongTime(data[idx]);
|
||||
assert(idx < size());
|
||||
return ParseCommandArgSongTime(args[idx]);
|
||||
}
|
||||
|
||||
SignedSongTime ParseSignedSongTime(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgSignedSongTime(data[idx]);
|
||||
assert(idx < size());
|
||||
return ParseCommandArgSignedSongTime(args[idx]);
|
||||
}
|
||||
|
||||
int ParseOptional(unsigned idx, int default_value) const {
|
||||
return idx < size
|
||||
return idx < size()
|
||||
? ParseInt(idx)
|
||||
: default_value;
|
||||
}
|
||||
|
||||
RangeArg ParseOptional(unsigned idx, RangeArg default_value) const {
|
||||
return idx < size
|
||||
return idx < size()
|
||||
? ParseRange(idx)
|
||||
: default_value;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ handle_sticker_song(Response &r, Partition &partition,
|
||||
const char *const cmd = args.front();
|
||||
|
||||
/* get song song_id key */
|
||||
if (args.size == 4 && StringIsEqual(cmd, "get")) {
|
||||
if (args.size() == 4 && StringIsEqual(cmd, "get")) {
|
||||
const LightSong *song = db.GetSong(args[2]);
|
||||
assert(song != nullptr);
|
||||
AtScopeExit(&db, song) { db.ReturnSong(song); };
|
||||
@ -75,7 +75,7 @@ handle_sticker_song(Response &r, Partition &partition,
|
||||
|
||||
return CommandResult::OK;
|
||||
/* list song song_id */
|
||||
} else if (args.size == 3 && StringIsEqual(cmd, "list")) {
|
||||
} else if (args.size() == 3 && StringIsEqual(cmd, "list")) {
|
||||
const LightSong *song = db.GetSong(args[2]);
|
||||
assert(song != nullptr);
|
||||
AtScopeExit(&db, song) { db.ReturnSong(song); };
|
||||
@ -85,7 +85,7 @@ handle_sticker_song(Response &r, Partition &partition,
|
||||
|
||||
return CommandResult::OK;
|
||||
/* set song song_id id key */
|
||||
} else if (args.size == 5 && StringIsEqual(cmd, "set")) {
|
||||
} else if (args.size() == 5 && StringIsEqual(cmd, "set")) {
|
||||
const LightSong *song = db.GetSong(args[2]);
|
||||
assert(song != nullptr);
|
||||
AtScopeExit(&db, song) { db.ReturnSong(song); };
|
||||
@ -94,13 +94,13 @@ handle_sticker_song(Response &r, Partition &partition,
|
||||
args[3], args[4]);
|
||||
return CommandResult::OK;
|
||||
/* delete song song_id [key] */
|
||||
} else if ((args.size == 3 || args.size == 4) &&
|
||||
} else if ((args.size() == 3 || args.size() == 4) &&
|
||||
StringIsEqual(cmd, "delete")) {
|
||||
const LightSong *song = db.GetSong(args[2]);
|
||||
assert(song != nullptr);
|
||||
AtScopeExit(&db, song) { db.ReturnSong(song); };
|
||||
|
||||
bool ret = args.size == 3
|
||||
bool ret = args.size() == 3
|
||||
? sticker_song_delete(sticker_database, *song)
|
||||
: sticker_song_delete_value(sticker_database, *song,
|
||||
args[3]);
|
||||
@ -111,7 +111,7 @@ handle_sticker_song(Response &r, Partition &partition,
|
||||
|
||||
return CommandResult::OK;
|
||||
/* find song dir key */
|
||||
} else if ((args.size == 4 || args.size == 6) &&
|
||||
} else if ((args.size() == 4 || args.size() == 6) &&
|
||||
StringIsEqual(cmd, "find")) {
|
||||
/* "sticker find song a/directory name" */
|
||||
|
||||
@ -120,7 +120,7 @@ handle_sticker_song(Response &r, Partition &partition,
|
||||
StickerOperator op = StickerOperator::EXISTS;
|
||||
const char *value = nullptr;
|
||||
|
||||
if (args.size == 6) {
|
||||
if (args.size() == 6) {
|
||||
/* match the value */
|
||||
|
||||
const char *op_s = args[4];
|
||||
@ -157,7 +157,7 @@ handle_sticker_song(Response &r, Partition &partition,
|
||||
CommandResult
|
||||
handle_sticker(Client &client, Request args, Response &r)
|
||||
{
|
||||
assert(args.size >= 3);
|
||||
assert(args.size() >= 3);
|
||||
|
||||
auto &instance = client.GetInstance();
|
||||
if (!instance.HasStickerDatabase()) {
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "Request.hxx"
|
||||
#include "time/ChronoUtil.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/ConstBuffer.hxx"
|
||||
#include "fs/Traits.hxx"
|
||||
#include "client/Client.hxx"
|
||||
#include "client/Response.hxx"
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "client/Response.hxx"
|
||||
#include "tag/ParseName.hxx"
|
||||
#include "queue/Playlist.hxx"
|
||||
#include "util/ConstBuffer.hxx"
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
@ -52,7 +51,7 @@ handle_cleartagid(Client &client, Request args, Response &r)
|
||||
unsigned song_id = args.ParseUnsigned(0);
|
||||
|
||||
TagType tag_type = TAG_NUM_OF_ITEM_TYPES;
|
||||
if (args.size >= 2) {
|
||||
if (args.size() >= 2) {
|
||||
const char *const tag_name = args[1];
|
||||
tag_type = tag_name_parse_i(tag_name);
|
||||
if (tag_type == TAG_NUM_OF_ITEM_TYPES) {
|
||||
|
Loading…
Reference in New Issue
Block a user