Program Listing for File register_cmd_parser.cpp
↰ Return to documentation for file (register_cmd_parser.cpp)
#include "register_cmd_parser.hpp"
#include <nlohmann/json.hpp>
#include <format>
#include <string>
std::vector<ReqData> RegisterMsgParser::parse_commands(const char* msg, size_t len)
{
std::vector<ReqData> parsed_messages;
simdjson::dom::element ops = parser.parse(simdjson::padded_string(msg, len));
simdjson::dom::array cmd_args;
for (simdjson::dom::object op : ops) {
ReqData parsed_msg;
//Parse UUID
std::string_view uuid_view = "";
parsed_msg.status_code = op[FelixClientThread::to_string(FelixClientThread::UUID)].get(uuid_view);
if (parsed_msg.status_code) {
parsed_msg.status_message = "Field 'uuid' not found";
}
parsed_msg.uuid = std::string(uuid_view);
//Parse CMD
std::string_view cmd_view = "";
if (!parsed_msg.status_code) {
parsed_msg.status_code = op[FelixClientThread::to_string(FelixClientThread::CMD)].get(cmd_view);
if (parsed_msg.status_code) {
parsed_msg.status_message = "Field 'cmd' not found";
}
}
parsed_msg.cmd = FelixClientThread::to_cmd(std::string(cmd_view));
//Parse register name and value
if (!parsed_msg.status_code) {
parsed_msg.status_code = op[FelixClientThread::to_string(FelixClientThread::CMD_ARGS)].get(cmd_args);
if (parsed_msg.status_code) {
parsed_msg.status_message = "Field 'cmd_args' not found";
} else {
for (unsigned int i = 0; i < cmd_args.size(); ++i) {
if ( i == 0 ) {parsed_msg.resource_name = std::string(cmd_args.at(i));}
else if ( i == 1 ) {parsed_msg.value = std::string(cmd_args.at(i));}
else {
parsed_msg.status_message = "Field 'cmd_args' not found";
}
}
}
}
if (parsed_msg.status_code == FelixClientThread::OK){
parse_cmd_args(parsed_msg, cmd_args);
}
parsed_messages.push_back(parsed_msg);
}
return parsed_messages;
}
void RegisterMsgParser::parse_cmd_args(ReqData& msg, simdjson::dom::array& arr)
{
switch(msg.cmd) {
case FelixClientThread::Cmd::UNKNOWN:
case FelixClientThread::TRIGGER: { //TRIGGER not supported yet.
msg.status_code = FelixClientThread::Status::ERROR_INVALID_CMD;
msg.value = "";
msg.status_message = "Invalid command";
break;
}
case FelixClientThread::Cmd::NOOP: {
if (arr.size() != 0) {
msg.status_code = FelixClientThread::ERROR_INVALID_ARGS;
msg.value = "";
msg.status_message = std::string("Invalid number of arguments, found ") + std::to_string(arr.size()) + ", 0 expected.";
}
break;
}
case FelixClientThread::Cmd::GET: {
if (arr.size() != 1) {
msg.status_code = FelixClientThread::ERROR_INVALID_ARGS;
msg.value = "";
msg.status_message = std::string("Invalid number of arguments, found ") + std::to_string(arr.size()) + ", 1 expected.";
} else {
msg.resource_name = std::string(arr.at(0));
}
break;
}
case FelixClientThread::ECR_RESET: {
if (arr.size() != 1) {
msg.status_code = FelixClientThread::ERROR_INVALID_ARGS;
msg.value = "";
msg.status_message = std::string("Invalid number of arguments, found ") + std::to_string(arr.size()) + ", 1 expected.";
} else {
msg.value = std::string(arr.at(0));
}
break;
}
case FelixClientThread::Cmd::SET: {
if (arr.size() != 2) {
msg.status_code = FelixClientThread::ERROR_INVALID_ARGS;
msg.value = "";
msg.status_message = std::string("Invalid number of arguments, found ") + std::to_string(arr.size()) + ", 2 expected.";
} else {
msg.resource_name = std::string(arr.at(0));
msg.value = std::string(arr.at(1));
}
break;
}
}
}
std::vector<ReqData> RegisterMsgParser::parse_commands(const std::string& cmd)
{
return parse_commands(cmd.c_str(), cmd.size());
}
std::string RegisterMsgParser::encode_commands(const std::vector<Command> & cmds)
{
nlohmann::json j = nlohmann::json::array();
for (unsigned int i = 0; i < cmds.size(); ++i) {
auto & entry = cmds[i];
j[i][FelixClientThread::to_string(FelixClientThread::UUID)] = entry.uuid;
j[i][FelixClientThread::to_string(FelixClientThread::CMD)] = FelixClientThread::to_string(entry.cmd);
j[i][FelixClientThread::to_string(FelixClientThread::CMD_ARGS)] = nlohmann::json(entry.cmd_args);
}
return j.dump();
}
std::string RegisterMsgParser::encode_replies(uint64_t fid, const std::vector<ReqData>& cmds)
{
nlohmann::json j = nlohmann::json::array();
for (unsigned int i = 0; i < cmds.size(); ++i) {
const auto & entry = cmds[i];
j[i]["ctrl_fid"] = std::format("{:#0x}", fid);
j[i][FelixClientThread::to_string(FelixClientThread::UUID)] = entry.uuid;
j[i][FelixClientThread::to_string(FelixClientThread::STATUS)] = entry.status_code;
j[i][FelixClientThread::to_string(FelixClientThread::MESSAGE)] = entry.status_message;
j[i][FelixClientThread::to_string(FelixClientThread::VALUE)] = (entry.value == "") ? 0 : std::stoul(entry.value, nullptr, 0);
}
return j.dump();
}
std::vector<FelixClientThread::Reply> RegisterMsgParser::decode_replies(const std::string & r)
{
std::vector<FelixClientThread::Reply> replies;
auto key_status = FelixClientThread::to_string(FelixClientThread::STATUS);
auto key_value = FelixClientThread::to_string(FelixClientThread::VALUE);
auto key_msg = FelixClientThread::to_string(FelixClientThread::MESSAGE);
auto j = nlohmann::json::parse(r);
for (const auto& item : j.items()) {
auto entry = item.value();
auto num_value = entry[key_value].template get<std::uint64_t>();
//unsigned long num_value = value.empty() ? 0 : std::stoul(value, nullptr, 16);
int status = static_cast<FelixClientThreadExtension::Status>(entry[key_status].template get<int>());
replies.emplace_back(
FelixClientThread::Reply {
.ctrl_fid = std::stoul(entry["ctrl_fid"].template get<std::string>(), nullptr, 16),
.status = static_cast<FelixClientThread::Status>(status),
.value = num_value,
.message = entry[key_msg].template get<std::string>(),
}
);
};
return replies;
}