diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/command/AllCommands.cxx | 1 | ||||
-rw-r--r-- | src/command/PartitionCommands.cxx | 70 | ||||
-rw-r--r-- | src/command/PartitionCommands.hxx | 3 |
3 files changed, 74 insertions, 0 deletions
diff --git a/src/command/AllCommands.cxx b/src/command/AllCommands.cxx index bcd0e368e..75e15d94d 100644 --- a/src/command/AllCommands.cxx +++ b/src/command/AllCommands.cxx @@ -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 }, diff --git a/src/command/PartitionCommands.cxx b/src/command/PartitionCommands.cxx index 1ccf5f85a..873b1dbe0 100644 --- a/src/command/PartitionCommands.cxx +++ b/src/command/PartitionCommands.cxx @@ -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; +} diff --git a/src/command/PartitionCommands.hxx b/src/command/PartitionCommands.hxx index e64bcf059..6c51beeb4 100644 --- a/src/command/PartitionCommands.hxx +++ b/src/command/PartitionCommands.hxx @@ -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 |