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 : }