command/Partition: add command "newpartition"
This commit is contained in:
parent
1e972174a6
commit
1786f9b1bb
@ -2376,6 +2376,20 @@ OK
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry id="command_newpartition">
|
||||
<term>
|
||||
<cmdsynopsis>
|
||||
<command>newpartition</command>
|
||||
<arg choice="req"><replaceable>NAME</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Create a new partition.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</section>
|
||||
|
||||
|
@ -133,6 +133,7 @@ static constexpr struct command commands[] = {
|
||||
#endif
|
||||
{ "move", PERMISSION_CONTROL, 2, 2, handle_move },
|
||||
{ "moveid", PERMISSION_CONTROL, 2, 2, handle_moveid },
|
||||
{ "newpartition", PERMISSION_ADMIN, 1, 1, handle_newpartition },
|
||||
{ "next", PERMISSION_CONTROL, 0, 0, handle_next },
|
||||
{ "notcommands", PERMISSION_NONE, 0, 0, handle_not_commands },
|
||||
{ "outputs", PERMISSION_READ, 0, 0, handle_devices },
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include "Partition.hxx"
|
||||
#include "client/Client.hxx"
|
||||
#include "client/Response.hxx"
|
||||
#include "player/Thread.hxx"
|
||||
#include "util/CharUtil.hxx"
|
||||
|
||||
CommandResult
|
||||
handle_listpartitions(Client &client, Request, Response &r)
|
||||
@ -34,3 +36,71 @@ handle_listpartitions(Client &client, Request, Response &r)
|
||||
|
||||
return CommandResult::OK;
|
||||
}
|
||||
|
||||
static constexpr bool
|
||||
IsValidPartitionChar(char ch)
|
||||
{
|
||||
return IsAlphaNumericASCII(ch) || ch == '-' || ch == '_';
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
static bool
|
||||
IsValidPartitionName(const char *name)
|
||||
{
|
||||
do {
|
||||
if (!IsValidPartitionChar(*name))
|
||||
return false;
|
||||
} while (*++name != 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
static bool
|
||||
HasPartitionNamed(const Instance &instance, const char *name)
|
||||
{
|
||||
for (const auto &partition : instance.partitions)
|
||||
if (partition.name == name)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CommandResult
|
||||
handle_newpartition(Client &client, Request request, Response &response)
|
||||
{
|
||||
const char *name = request.front();
|
||||
if (!IsValidPartitionName(name)) {
|
||||
response.Error(ACK_ERROR_ARG, "bad name");
|
||||
return CommandResult::ERROR;
|
||||
}
|
||||
|
||||
auto &instance = client.partition.instance;
|
||||
if (HasPartitionNamed(instance, name)) {
|
||||
response.Error(ACK_ERROR_EXIST, "name already exists");
|
||||
return CommandResult::ERROR;
|
||||
}
|
||||
|
||||
if (instance.partitions.size() >= 16) {
|
||||
/* arbitrary limit for now */
|
||||
response.Error(ACK_ERROR_UNKNOWN, "too many partitions");
|
||||
return CommandResult::ERROR;
|
||||
}
|
||||
|
||||
instance.partitions.emplace_back(instance, name,
|
||||
// TODO: use real configuration
|
||||
16384,
|
||||
1024,
|
||||
128,
|
||||
AudioFormat::Undefined(),
|
||||
ReplayGainConfig());
|
||||
auto &partition = instance.partitions.back();
|
||||
partition.outputs.AddNullOutput(instance.io_thread.GetEventLoop(),
|
||||
ReplayGainConfig(),
|
||||
partition.pc);
|
||||
partition.UpdateEffectiveReplayGainMode();
|
||||
StartPlayerThread(partition.pc);
|
||||
partition.pc.LockUpdateAudio();
|
||||
|
||||
return CommandResult::OK;
|
||||
}
|
||||
|
@ -29,4 +29,7 @@ class Response;
|
||||
CommandResult
|
||||
handle_listpartitions(Client &client, Request request, Response &response);
|
||||
|
||||
CommandResult
|
||||
handle_newpartition(Client &client, Request request, Response &response);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user