diff --git a/CMakeLists.txt b/CMakeLists.txt index b9d44cf..5b1358a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -215,6 +215,9 @@ INSTALL ( set(TEST_LIBRARIES threadpool::static #Static + TeaSpeak #Static + TeaLicenseHelper #Static + TeaMusic #Static CXXTerminal::static #Static ${StringVariable_LIBRARIES_STATIC} ${YAML_CPP_LIBRARIES} @@ -240,8 +243,8 @@ set(TEST_LIBRARIES mysqlclient.a jsoncpp_lib ${ed25519_LIBRARIES_STATIC} - ${DataPipes_LIBRARIES_SHARED} - ffi + ${DataPipes_LIBRARIES_SHARED} # Also includes glib2.0 + openssl::ssl::shared openssl::crypto::shared dl diff --git a/src/query/command3.h b/src/query/command3.h index b7bf342..e4a4e9c 100644 --- a/src/query/command3.h +++ b/src/query/command3.h @@ -86,6 +86,30 @@ namespace ts { struct command_bulk : public impl::command_string_parser { command_bulk(size_t index, std::string_view data) : command_string_parser{index, std::move(data)} {} + + inline bool next_entry(size_t& index, std::string_view& key, std::string& value) const { + auto next_key = this->data.find_first_not_of(' ', index); + if(next_key == std::string::npos) return false; + + auto key_end = this->data.find_first_of(" =", next_key); + if(key_end == std::string::npos || this->data[key_end] == ' ') { + key = this->data.substr(next_key, key_end - next_key); + value.clear(); + index = key_end; + } else { + key = this->data.substr(next_key, key_end - next_key); + auto value_end = this->data.find_first_of(' ', key_end + 1); + + if(value_end == std::string::npos) { + value = query::unescape(value = this->data.substr(key_end + 1), false); + index = value_end; + } else { + value = query::unescape(value = this->data.substr(key_end + 1, value_end - key_end - 1), false); + index = value_end + 1; + } + } + return true; + } }; class command_parser : public impl::command_string_parser { diff --git a/test/CommandTest.cpp b/test/CommandTest.cpp index 593608d..a0b8d83 100644 --- a/test/CommandTest.cpp +++ b/test/CommandTest.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "PermissionManager.h" #include "src/query/command_handler.h" @@ -68,6 +69,19 @@ void eval_test(command_result x) { } } +void print_entries(const ts::command_parser& parser) { + size_t index; + std::string_view key{}; + std::string value{}; + for(const auto& bulk : parser.bulks()) { + std::cout << "----\n"; + index = 0; + while(bulk.next_entry(index, key, value)) { + std::cout << " " << key << " => " << value << "\n"; + } + } +} + int main() { ts::command_handler::impl::field::as_bulked a; std::cout << "Optional: " << a.is_optional() << "\n"; @@ -118,16 +132,12 @@ int main() { ts::command cmd("notify"); */ - /* - cout << ts::command::parse("test a=b ").build(ts::command::format::BRACE_ESCAPED_QUERY) << endl; - cout << ts::command::parse("test a=").build(ts::command::format::BRACE_ESCAPED_QUERY) << endl; - cout << ts::command::parse("test a").build(ts::command::format::BRACE_ESCAPED_QUERY) << endl; - cout << ts::command::parse("a=c", false).build(ts::command::format::BRACE_ESCAPED_QUERY) << endl; - cout << ts::command::parse("a=c | a=c -x", false).build(ts::command::format::BRACE_ESCAPED_QUERY) << endl; - cout << ts::command::parse("a a=c|a=c").build(ts::command::format::BRACE_ESCAPED_QUERY) << endl; - cout << ts::command::parse("a a=c a=c2 -z | -? a=c").build(ts::command::format::BRACE_ESCAPED_QUERY) << endl; - */ + auto command = ts::command_parser{"a a=c a=c2 -z |-? a=2 key_c=c"}; + if(!command.parse(true)) return 1; + print_entries(command); + + return 0; std::cout << "Command v3:\n"; { auto command = ts::command_parser{"a a=c a=c2 -z | -? a=2 key_c=c"};