protocol/ArgParser: add struct RangeArg
This commit is contained in:
parent
993df0fd28
commit
cbdc3194cc
@ -67,15 +67,15 @@ handle_lsinfo2(Client &client, ConstBuffer<const char *> args)
|
|||||||
static CommandResult
|
static CommandResult
|
||||||
handle_match(Client &client, ConstBuffer<const char *> args, bool fold_case)
|
handle_match(Client &client, ConstBuffer<const char *> args, bool fold_case)
|
||||||
{
|
{
|
||||||
unsigned window_start = 0, window_end = std::numeric_limits<int>::max();
|
RangeArg window;
|
||||||
if (args.size >= 2 && strcmp(args[args.size - 2], "window") == 0) {
|
if (args.size >= 2 && strcmp(args[args.size - 2], "window") == 0) {
|
||||||
if (!check_range(client, &window_start, &window_end,
|
if (!ParseCommandArg(client, window, args.back()))
|
||||||
args.back()))
|
|
||||||
return CommandResult::ERROR;
|
return CommandResult::ERROR;
|
||||||
|
|
||||||
args.pop_back();
|
args.pop_back();
|
||||||
args.pop_back();
|
args.pop_back();
|
||||||
}
|
} else
|
||||||
|
window.SetAll();
|
||||||
|
|
||||||
SongFilter filter;
|
SongFilter filter;
|
||||||
if (!filter.Parse(args, fold_case)) {
|
if (!filter.Parse(args, fold_case)) {
|
||||||
@ -87,7 +87,7 @@ handle_match(Client &client, ConstBuffer<const char *> args, bool fold_case)
|
|||||||
|
|
||||||
Error error;
|
Error error;
|
||||||
return db_selection_print(client, selection, true, false,
|
return db_selection_print(client, selection, true, false,
|
||||||
window_start, window_end, error)
|
window.start, window.end, error)
|
||||||
? CommandResult::OK
|
? CommandResult::OK
|
||||||
: print_error(client, error);
|
: print_error(client, error);
|
||||||
}
|
}
|
||||||
|
@ -70,12 +70,10 @@ handle_save(Client &client, ConstBuffer<const char *> args)
|
|||||||
CommandResult
|
CommandResult
|
||||||
handle_load(Client &client, ConstBuffer<const char *> args)
|
handle_load(Client &client, ConstBuffer<const char *> args)
|
||||||
{
|
{
|
||||||
unsigned start_index, end_index;
|
RangeArg range;
|
||||||
|
if (args.size < 2)
|
||||||
if (args.size < 2) {
|
range.SetAll();
|
||||||
start_index = 0;
|
else if (!ParseCommandArg(client, range, args[1]))
|
||||||
end_index = unsigned(-1);
|
|
||||||
} else if (!check_range(client, &start_index, &end_index, args[1]))
|
|
||||||
return CommandResult::ERROR;
|
return CommandResult::ERROR;
|
||||||
|
|
||||||
const ScopeBulkEdit bulk_edit(client.partition);
|
const ScopeBulkEdit bulk_edit(client.partition);
|
||||||
@ -83,7 +81,7 @@ handle_load(Client &client, ConstBuffer<const char *> args)
|
|||||||
Error error;
|
Error error;
|
||||||
const SongLoader loader(client);
|
const SongLoader loader(client);
|
||||||
if (!playlist_open_into_queue(args.front(),
|
if (!playlist_open_into_queue(args.front(),
|
||||||
start_index, end_index,
|
range.start, range.end,
|
||||||
client.playlist,
|
client.playlist,
|
||||||
client.player_control, loader, error))
|
client.player_control, loader, error))
|
||||||
return print_error(client, error);
|
return print_error(client, error);
|
||||||
|
@ -175,12 +175,11 @@ handle_rangeid(Client &client, ConstBuffer<const char *> args)
|
|||||||
CommandResult
|
CommandResult
|
||||||
handle_delete(Client &client, ConstBuffer<const char *> args)
|
handle_delete(Client &client, ConstBuffer<const char *> args)
|
||||||
{
|
{
|
||||||
unsigned start, end;
|
RangeArg range;
|
||||||
|
if (!ParseCommandArg(client, range, args.front()))
|
||||||
if (!check_range(client, &start, &end, args.front()))
|
|
||||||
return CommandResult::ERROR;
|
return CommandResult::ERROR;
|
||||||
|
|
||||||
PlaylistResult result = client.partition.DeleteRange(start, end);
|
auto result = client.partition.DeleteRange(range.start, range.end);
|
||||||
return print_playlist_result(client, result);
|
return print_playlist_result(client, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,11 +205,13 @@ handle_playlist(Client &client, gcc_unused ConstBuffer<const char *> args)
|
|||||||
CommandResult
|
CommandResult
|
||||||
handle_shuffle(gcc_unused Client &client, ConstBuffer<const char *> args)
|
handle_shuffle(gcc_unused Client &client, ConstBuffer<const char *> args)
|
||||||
{
|
{
|
||||||
unsigned start = 0, end = client.playlist.queue.GetLength();
|
RangeArg range;
|
||||||
if (args.size == 1 && !check_range(client, &start, &end, args.front()))
|
if (args.IsEmpty())
|
||||||
|
range.SetAll();
|
||||||
|
else if (!ParseCommandArg(client, range, args.front()))
|
||||||
return CommandResult::ERROR;
|
return CommandResult::ERROR;
|
||||||
|
|
||||||
client.partition.Shuffle(start, end);
|
client.partition.Shuffle(range.start, range.end);
|
||||||
return CommandResult::OK;
|
return CommandResult::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,12 +249,14 @@ handle_plchangesposid(Client &client, ConstBuffer<const char *> args)
|
|||||||
CommandResult
|
CommandResult
|
||||||
handle_playlistinfo(Client &client, ConstBuffer<const char *> args)
|
handle_playlistinfo(Client &client, ConstBuffer<const char *> args)
|
||||||
{
|
{
|
||||||
unsigned start = 0, end = std::numeric_limits<unsigned>::max();
|
RangeArg range;
|
||||||
|
if (args.IsEmpty())
|
||||||
if (args.size == 1 && !check_range(client, &start, &end, args.front()))
|
range.SetAll();
|
||||||
|
else if (!ParseCommandArg(client, range, args.front()))
|
||||||
return CommandResult::ERROR;
|
return CommandResult::ERROR;
|
||||||
|
|
||||||
if (!playlist_print_info(client, client.playlist, start, end))
|
if (!playlist_print_info(client, client.playlist,
|
||||||
|
range.start, range.end))
|
||||||
return print_playlist_result(client,
|
return print_playlist_result(client,
|
||||||
PlaylistResult::BAD_RANGE);
|
PlaylistResult::BAD_RANGE);
|
||||||
|
|
||||||
@ -322,14 +325,14 @@ handle_prio(Client &client, ConstBuffer<const char *> args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const char *i : args) {
|
for (const char *i : args) {
|
||||||
unsigned start_position, end_position;
|
RangeArg range;
|
||||||
if (!check_range(client, &start_position, &end_position, i))
|
if (!ParseCommandArg(client, range, i))
|
||||||
return CommandResult::ERROR;
|
return CommandResult::ERROR;
|
||||||
|
|
||||||
PlaylistResult result =
|
PlaylistResult result =
|
||||||
client.partition.SetPriorityRange(start_position,
|
client.partition.SetPriorityRange(range.start,
|
||||||
end_position,
|
range.end,
|
||||||
priority);
|
priority);
|
||||||
if (result != PlaylistResult::SUCCESS)
|
if (result != PlaylistResult::SUCCESS)
|
||||||
return print_playlist_result(client, result);
|
return print_playlist_result(client, result);
|
||||||
}
|
}
|
||||||
@ -369,16 +372,16 @@ handle_prioid(Client &client, ConstBuffer<const char *> args)
|
|||||||
CommandResult
|
CommandResult
|
||||||
handle_move(Client &client, ConstBuffer<const char *> args)
|
handle_move(Client &client, ConstBuffer<const char *> args)
|
||||||
{
|
{
|
||||||
unsigned start, end;
|
RangeArg range;
|
||||||
int to;
|
int to;
|
||||||
|
|
||||||
if (!check_range(client, &start, &end, args[0]))
|
if (!ParseCommandArg(client, range, args[0]))
|
||||||
return CommandResult::ERROR;
|
return CommandResult::ERROR;
|
||||||
if (!check_int(client, &to, args[1]))
|
if (!check_int(client, &to, args[1]))
|
||||||
return CommandResult::ERROR;
|
return CommandResult::ERROR;
|
||||||
|
|
||||||
PlaylistResult result =
|
PlaylistResult result =
|
||||||
client.partition.MoveRange(start, end, to);
|
client.partition.MoveRange(range.start, range.end, to);
|
||||||
return print_playlist_result(client, result);
|
return print_playlist_result(client, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,8 +65,7 @@ check_int(Client &client, int *value_r, const char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
check_range(Client &client, unsigned *value_r1, unsigned *value_r2,
|
ParseCommandArg(Client &client, RangeArg &value_r, const char *s)
|
||||||
const char *s)
|
|
||||||
{
|
{
|
||||||
char *test, *test2;
|
char *test, *test2;
|
||||||
long value;
|
long value;
|
||||||
@ -81,8 +80,8 @@ check_range(Client &client, unsigned *value_r1, unsigned *value_r2,
|
|||||||
if (value == -1 && *test == 0) {
|
if (value == -1 && *test == 0) {
|
||||||
/* compatibility with older MPD versions: specifying
|
/* compatibility with older MPD versions: specifying
|
||||||
"-1" makes MPD display the whole list */
|
"-1" makes MPD display the whole list */
|
||||||
*value_r1 = 0;
|
value_r.start = 0;
|
||||||
*value_r2 = std::numeric_limits<int>::max();
|
value_r.end = std::numeric_limits<int>::max();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +97,7 @@ check_range(Client &client, unsigned *value_r1, unsigned *value_r2,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*value_r1 = (unsigned)value;
|
value_r.start = (unsigned)value;
|
||||||
|
|
||||||
if (*test == ':') {
|
if (*test == ':') {
|
||||||
value = strtol(++test, &test2, 10);
|
value = strtol(++test, &test2, 10);
|
||||||
@ -123,9 +122,9 @@ check_range(Client &client, unsigned *value_r1, unsigned *value_r2,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*value_r2 = (unsigned)value;
|
value_r.end = (unsigned)value;
|
||||||
} else {
|
} else {
|
||||||
*value_r2 = (unsigned)value + 1;
|
value_r.end = (unsigned)value + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -34,9 +34,17 @@ check_uint32(Client &client, uint32_t *dst, const char *s);
|
|||||||
bool
|
bool
|
||||||
check_int(Client &client, int *value_r, const char *s);
|
check_int(Client &client, int *value_r, const char *s);
|
||||||
|
|
||||||
|
struct RangeArg {
|
||||||
|
unsigned start, end;
|
||||||
|
|
||||||
|
void SetAll() {
|
||||||
|
start = 0;
|
||||||
|
end = unsigned(-1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
check_range(Client &client, unsigned *value_r1, unsigned *value_r2,
|
ParseCommandArg(Client &client, RangeArg &value_r, const char *s);
|
||||||
const char *s);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
check_unsigned(Client &client, unsigned *value_r, const char *s);
|
check_unsigned(Client &client, unsigned *value_r, const char *s);
|
||||||
|
@ -32,21 +32,22 @@ void
|
|||||||
ArgParserTest::TestRange()
|
ArgParserTest::TestRange()
|
||||||
{
|
{
|
||||||
Client &client = *(Client *)nullptr;
|
Client &client = *(Client *)nullptr;
|
||||||
unsigned a, b;
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT(check_range(client, &a, &b, "1"));
|
RangeArg range;
|
||||||
CPPUNIT_ASSERT_EQUAL(1u, a);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(2u, b);
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT(check_range(client, &a, &b, "1:5"));
|
CPPUNIT_ASSERT(ParseCommandArg(client, range, "1"));
|
||||||
CPPUNIT_ASSERT_EQUAL(1u, a);
|
CPPUNIT_ASSERT_EQUAL(1u, range.start);
|
||||||
CPPUNIT_ASSERT_EQUAL(5u, b);
|
CPPUNIT_ASSERT_EQUAL(2u, range.end);
|
||||||
|
|
||||||
CPPUNIT_ASSERT(check_range(client, &a, &b, "1:"));
|
CPPUNIT_ASSERT(ParseCommandArg(client, range, "1:5"));
|
||||||
CPPUNIT_ASSERT_EQUAL(1u, a);
|
CPPUNIT_ASSERT_EQUAL(1u, range.start);
|
||||||
CPPUNIT_ASSERT(b >= 999999u);
|
CPPUNIT_ASSERT_EQUAL(5u, range.end);
|
||||||
|
|
||||||
CPPUNIT_ASSERT(!check_range(client, &a, &b, "-2"));
|
CPPUNIT_ASSERT(ParseCommandArg(client, range, "1:"));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(1u, range.start);
|
||||||
|
CPPUNIT_ASSERT(range.end >= 999999u);
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT(!ParseCommandArg(client, range, "-2"));
|
||||||
CPPUNIT_ASSERT_EQUAL(ACK_ERROR_ARG, last_error);
|
CPPUNIT_ASSERT_EQUAL(ACK_ERROR_ARG, last_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user