64 lines
1.7 KiB
C++
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
|