mountcontrol/cxx/control_proto.cpp

64 lines
1.7 KiB
C++

#include "control_proto.h"
#include <ranges>
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_result_t> ControlProtoParser::parse(std::string_view command)
{
std::optional<ControlProtoParser::parse_result_t> 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