LCOV - code coverage report
Current view: top level - felix-star/src - register_cmd_parser.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 91 104 87.5 %
Date: 2025-08-12 04:15:35 Functions: 6 6 100.0 %

          Line data    Source code
       1             : #include "register_cmd_parser.hpp"
       2             : #include <nlohmann/json.hpp>
       3             : #include <format>
       4             : #include <string>
       5             : 
       6             : 
       7           9 : std::vector<ReqData> RegisterMsgParser::parse_commands(const char* msg, size_t len)
       8             : {
       9           9 :     std::vector<ReqData> parsed_messages;
      10           9 :     simdjson::dom::element ops = parser.parse(simdjson::padded_string(msg, len));
      11           9 :     simdjson::dom::array cmd_args;
      12             : 
      13          20 :     for (simdjson::dom::object op : ops) {
      14          11 :         ReqData parsed_msg;
      15             :         //Parse UUID
      16          11 :         std::string_view uuid_view = "";
      17          21 :         parsed_msg.status_code = op[FelixClientThread::to_string(FelixClientThread::UUID)].get(uuid_view);
      18          11 :         if (parsed_msg.status_code) {
      19           1 :             parsed_msg.status_message = "Field 'uuid' not found";
      20             :         }
      21          22 :         parsed_msg.uuid = std::string(uuid_view);
      22             : 
      23             :         //Parse CMD
      24          11 :         std::string_view cmd_view = "";
      25          11 :         if (!parsed_msg.status_code) {
      26          19 :             parsed_msg.status_code = op[FelixClientThread::to_string(FelixClientThread::CMD)].get(cmd_view);
      27          10 :             if (parsed_msg.status_code) {
      28           1 :                 parsed_msg.status_message = "Field 'cmd' not found";
      29             :             }
      30             :         }
      31          22 :         parsed_msg.cmd = FelixClientThread::to_cmd(std::string(cmd_view));
      32             : 
      33             :         //Parse register name and value
      34          11 :         if (!parsed_msg.status_code) {
      35          17 :             parsed_msg.status_code = op[FelixClientThread::to_string(FelixClientThread::CMD_ARGS)].get(cmd_args);
      36           9 :             if (parsed_msg.status_code) {
      37           1 :                 parsed_msg.status_message = "Field 'cmd_args' not found";
      38             :             } else {
      39          18 :                 for (unsigned int i = 0; i < cmd_args.size(); ++i) {
      40          10 :                     if ( i == 0 ) {parsed_msg.resource_name = std::string(cmd_args.at(i));}
      41           4 :                     else if ( i == 1 ) {parsed_msg.value = std::string(cmd_args.at(i));}
      42             :                     else {
      43          10 :                         parsed_msg.status_message = "Field 'cmd_args' not found";
      44             :                     }
      45             :                 }
      46             :             }
      47             :         }
      48             :         
      49          11 :         if (parsed_msg.status_code == FelixClientThread::OK){
      50           8 :             parse_cmd_args(parsed_msg, cmd_args);
      51             :         }
      52             : 
      53          11 :         parsed_messages.push_back(parsed_msg);
      54          11 :     }
      55             : 
      56           9 :     return parsed_messages;
      57           0 : }
      58             : 
      59             : 
      60           8 : void RegisterMsgParser::parse_cmd_args(ReqData& msg, simdjson::dom::array& arr)
      61             : {
      62           8 :     switch(msg.cmd) {
      63           1 :         case FelixClientThread::Cmd::UNKNOWN:
      64           1 :         case FelixClientThread::TRIGGER: {  //TRIGGER not supported yet.
      65           1 :             msg.status_code = FelixClientThread::Status::ERROR_INVALID_CMD;
      66           1 :             msg.value = "";
      67           1 :             msg.status_message = "Invalid command";
      68           1 :             break;
      69             :         }
      70           1 :         case FelixClientThread::Cmd::NOOP: {
      71           1 :             if (arr.size() != 0) {
      72           0 :                 msg.status_code = FelixClientThread::ERROR_INVALID_ARGS;
      73           0 :                 msg.value = "";
      74           0 :                 msg.status_message = std::string("Invalid number of arguments, found ") + std::to_string(arr.size()) + ", 0 expected.";
      75             :             } 
      76             :             break;
      77             :         }
      78           1 :         case FelixClientThread::Cmd::GET: {
      79           1 :             if (arr.size() != 1) {
      80           0 :                 msg.status_code = FelixClientThread::ERROR_INVALID_ARGS;
      81           0 :                 msg.value = "";
      82           0 :                 msg.status_message = std::string("Invalid number of arguments, found ") + std::to_string(arr.size()) + ", 1 expected.";
      83             :             } else {
      84           1 :                 msg.resource_name = std::string(arr.at(0));
      85             :             }
      86             :             break;
      87             :         }
      88           0 :         case FelixClientThread::ECR_RESET: {
      89           0 :             if (arr.size() != 1) {
      90           0 :                 msg.status_code = FelixClientThread::ERROR_INVALID_ARGS;
      91           0 :                 msg.value = "";
      92           0 :                 msg.status_message = std::string("Invalid number of arguments, found ") + std::to_string(arr.size()) + ", 1 expected.";
      93             :             } else {
      94           0 :                 msg.value = std::string(arr.at(0));
      95             :             }
      96             :             break;
      97             :         }
      98           5 :         case FelixClientThread::Cmd::SET: {
      99           5 :             if (arr.size() != 2) {
     100           1 :                 msg.status_code = FelixClientThread::ERROR_INVALID_ARGS;
     101           1 :                 msg.value = "";
     102           2 :                 msg.status_message = std::string("Invalid number of arguments, found ") + std::to_string(arr.size()) + ", 2 expected.";
     103             :             } else {
     104           4 :                 msg.resource_name = std::string(arr.at(0));
     105           4 :                 msg.value = std::string(arr.at(1));
     106             :             }
     107             :             break;
     108             :         }
     109             :     }
     110           8 : }
     111             : 
     112             : 
     113           9 : std::vector<ReqData> RegisterMsgParser::parse_commands(const std::string& cmd)
     114             : {
     115           9 :     return parse_commands(cmd.c_str(), cmd.size());
     116             : }
     117             : 
     118             : 
     119           6 : std::string RegisterMsgParser::encode_commands(const std::vector<Command> & cmds)
     120             : {
     121           6 :     nlohmann::json j = nlohmann::json::array();
     122          14 :     for (unsigned int i = 0; i < cmds.size(); ++i) {
     123           8 :         auto & entry = cmds[i];
     124           8 :         j[i][FelixClientThread::to_string(FelixClientThread::UUID)]  = entry.uuid;
     125           8 :         j[i][FelixClientThread::to_string(FelixClientThread::CMD)]   = FelixClientThread::to_string(entry.cmd);
     126           8 :         j[i][FelixClientThread::to_string(FelixClientThread::CMD_ARGS)]  = nlohmann::json(entry.cmd_args);
     127             :     }
     128          12 :     return j.dump();
     129           6 : }
     130             : 
     131             : 
     132             : 
     133           9 : std::string RegisterMsgParser::encode_replies(uint64_t fid, const std::vector<ReqData>& cmds)
     134             : {
     135           9 :     nlohmann::json j = nlohmann::json::array();
     136          20 :     for (unsigned int i = 0; i < cmds.size(); ++i) {
     137          11 :         const auto & entry = cmds[i];
     138          11 :         j[i]["ctrl_fid"] = std::format("{:#0x}", fid);
     139          11 :         j[i][FelixClientThread::to_string(FelixClientThread::UUID)]    = entry.uuid;
     140          11 :         j[i][FelixClientThread::to_string(FelixClientThread::STATUS)]  = entry.status_code;
     141          11 :         j[i][FelixClientThread::to_string(FelixClientThread::MESSAGE)] = entry.status_message;
     142          11 :         j[i][FelixClientThread::to_string(FelixClientThread::VALUE)]   = (entry.value == "") ? 0 : std::stoul(entry.value, nullptr, 0);
     143             :     }
     144          18 :     return j.dump();
     145           9 : }
     146             : 
     147             : 
     148           9 : std::vector<FelixClientThread::Reply> RegisterMsgParser::decode_replies(const std::string & r)
     149             : {
     150           9 :     std::vector<FelixClientThread::Reply> replies;
     151           9 :     auto key_status = FelixClientThread::to_string(FelixClientThread::STATUS);
     152           9 :     auto key_value = FelixClientThread::to_string(FelixClientThread::VALUE);
     153           9 :     auto key_msg = FelixClientThread::to_string(FelixClientThread::MESSAGE);
     154             : 
     155           9 :     auto j = nlohmann::json::parse(r);
     156          20 :     for (const auto& item : j.items()) {
     157             : 
     158          11 :         auto entry = item.value();
     159             : 
     160          11 :         auto num_value = entry[key_value].template get<std::uint64_t>();
     161             :         //unsigned long num_value = value.empty() ? 0 : std::stoul(value, nullptr, 16);
     162          11 :         int status = static_cast<FelixClientThreadExtension::Status>(entry[key_status].template get<int>());
     163             : 
     164          11 :         replies.emplace_back(
     165          22 :             FelixClientThread::Reply {
     166          11 :                 .ctrl_fid = std::stoul(entry["ctrl_fid"].template get<std::string>(), nullptr, 16),
     167          11 :                 .status  = static_cast<FelixClientThread::Status>(status),
     168             :                 .value   = num_value,
     169          11 :                 .message = entry[key_msg].template get<std::string>(),
     170             :             }
     171             :         );
     172          20 :     };
     173          18 :     return replies;
     174           9 : }

Generated by: LCOV version 1.0