#include "control_proto.h" #include namespace BM700 { void ControlProtoParser::generateCommMap() { for (auto& cmd : CONTROL_PROTO_VALID_COMMAND) { ControlProtoParser::_userFunc[cmd] = {}; } } ControlProtoParser::ControlProtoParser() { // generate user functions table only once if (ControlProtoParser::_userFunc.empty()) { generateCommMap(); } } std::optional ControlProtoParser::parse(std::string_view command) { std::optional ret = std::nullopt; auto found = std::ranges::search(command, CONTROL_PROTO_COMM_ARG_DELIM_SEQ); if (found.empty()) { // no command arguments if (ControlProtoParser::_userFunc.find(command) != ControlProtoParser::_userFunc.end()) { ret = ControlProtoParser::parse_result_t{command, {}}; } } else { ret = ControlProtoParser::parse_result_t{{command.begin(), found.begin()}, {}}; if (ControlProtoParser::_userFunc.find(ret->cmd) != ControlProtoParser::_userFunc.end()) { auto args = command | std::views::drop(std::distance(command.begin(), found.end())) | std::views::split(CONTROL_PROTO_ARG_DELIM_SEQ); for (const auto& el : args) { ret->args.emplace_back(el.begin(), el.end()); } } } return ret; } bool ControlProtoParser::exec(std::string_view command) { auto r = parse(command); if (r) { auto func = ControlProtoParser::_userFunc[r->cmd]; if (func) { func(r->cmd, r->args); return true; } } return false; } } // namespace BM700