# HG changeset patch # User František Kučera # Date 1659141213 -7200 # Node ID f0c51bc4d1648ce001c1cd5738f1aba38b73fd19 # Parent e57e2a2798b22cddd491a4efbd018c63e3d8bbf8 configuration: parse the connection string diff -r e57e2a2798b2 -r f0c51bc4d164 src/CLIParser.h --- a/src/CLIParser.h Sat Jul 30 00:16:40 2022 +0200 +++ b/src/CLIParser.h Sat Jul 30 02:33:33 2022 +0200 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -48,11 +49,11 @@ else throw relpipe::cli::RelpipeCLIException(L"Unable to parse boolean value: " + value + L" (expecting true or false)", relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS); } - void setIfMissing(std::vector& options, const std::string& name, const std::string& value) { + void setIfMissing(std::vector& options, const std::string& name, const std::string& value, bool includeEmptyValues = true) { auto n = convertor.from_bytes(name); auto v = convertor.from_bytes(value); for (auto o : options) if (o.name == n) return; - options.push_back({n, v}); + if (value.size() || includeEmptyValues) options.push_back({n, v}); } public: @@ -63,6 +64,7 @@ Configuration parse(const std::vector& arguments) { Configuration c; + relpipe::common::type::StringX connectionString; for (int i = 0; i < arguments.size();) { relpipe::common::type::StringX option = readNext(arguments, i); @@ -70,8 +72,7 @@ if (option == OPTION_RELATION) { c.relation = readNext(arguments, i); } else if (option == OPTION_CONNECTION_STRING) { - auto connectionString = readNext(arguments, i); - // FIXME: parse connection string and convert it to options + connectionString = readNext(arguments, i); } else if (option == OPTION_CONNECTION_OPTION) { auto name = readNext(arguments, i); auto value = readNext(arguments, i); @@ -80,6 +81,25 @@ } using namespace options; + + // Parse the connection string and convert it to options: + if (connectionString.size()) { + std::string connectionStringBytes = convertor.to_bytes(connectionString); + std::regex pattern("(tcp|udp|sctp)://([^:]+):([0-9]+)|(uds)://(.*)"); + std::smatch match; + if (std::regex_match(connectionStringBytes, match, pattern)) { + setIfMissing(c.options, OPTION_PROTOCOL, match[1], false); + setIfMissing(c.options, OPTION_PROTOCOL, match[4], false); + setIfMissing(c.options, OPTION_HOST, match[2], false); + setIfMissing(c.options, OPTION_PORT, match[3], false); + setIfMissing(c.options, OPTION_PATH, match[5], false); + if (match[1] == PROTOCOL_TCP) setIfMissing(c.options, OPTION_MODE, MODE_STREAM); + } else { + throw relpipe::cli::RelpipeCLIException(L"Invalid connection string: " + connectionString, relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS); + } + } + + // Set defaults when values are missing: setIfMissing(c.options, OPTION_PROTOCOL, PROTOCOL_UDP); setIfMissing(c.options, OPTION_ROLE, ROLE_CLIENT); setIfMissing(c.options, OPTION_MODE, MODE_DATAGRAM);