Skip to content

Commit

Permalink
add telegramoptions helper class and it's usage to telegramsolver
Browse files Browse the repository at this point in the history
  • Loading branch information
w0lek committed Nov 22, 2023
1 parent d64db1c commit 22bbf9c
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 36 deletions.
7 changes: 7 additions & 0 deletions vpr/src/server/keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ constexpr const char* KEY_DATA = "DATA";
constexpr const char* KEY_STATUS = "STATUS";
constexpr const unsigned char TELEGRAM_FRAME_DELIMETER{0x17}; // 0x17 - End of Transmission Block

constexpr const char* OPTION_PATH_NUM = "path_num";
constexpr const char* OPTION_PATH_TYPE = "path_type";
constexpr const char* OPTION_DETAILS_LEVEL = "details_level";
constexpr const char* OPTION_IS_FLOAT_ROUTING = "is_flat_routing";
constexpr const char* OPTION_PATH_INDEX = "path_index";
constexpr const char* OPTION_HIGHTLIGHT_MODE = "hight_light_mode";

enum CMD {
CMD_GET_PATH_LIST_ID=0,
CMD_DRAW_PATH_ID
Expand Down
34 changes: 14 additions & 20 deletions vpr/src/server/taskresolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#ifndef STANDALONE_APP
#include "globals.h"
#include "pathhelper.h"
#include "telegramoptions.h"
#include "telegramparser.h"
#include <gtk/gtk.h>
#include <ezgl/application.hpp>
Expand Down Expand Up @@ -72,15 +73,14 @@ void TaskResolver::update(ezgl::application* app)
{
for (auto& task: m_tasks) {
if (!task.isFinished()) {
// ugly, but let's have it for now
std::vector<std::string> optionsList = splitString(task.options(), ';');
TelegramOptions options{task.options()};
if (task.cmd() == CMD_GET_PATH_LIST_ID) {
if (optionsList.size() == 4) {
int nCriticalPathNum = std::atoi(optionsList[0].c_str());
std::string typePath = optionsList[1];
int detailsLevel = std::atoi(optionsList[2].c_str());
bool isFlat = std::atoi(optionsList[3].c_str());

options.validateNamePresence({OPTION_PATH_NUM, OPTION_PATH_TYPE, OPTION_DETAILS_LEVEL, OPTION_IS_FLOAT_ROUTING});
int nCriticalPathNum = options.getInt(OPTION_PATH_NUM, 1);
std::string typePath = options.getString(OPTION_PATH_TYPE);
int detailsLevel = options.getInt(OPTION_DETAILS_LEVEL, 0);
bool isFlat = options.getBool(OPTION_IS_FLOAT_ROUTING, false);
if (!options.hasErrors()) {
calcCritPath(nCriticalPathNum, typePath);
std::string msg = getPathsStr(g_vpr_ctx.crit_paths, detailsLevel, isFlat);
if (typePath != g_vpr_ctx.path_type) {
Expand All @@ -89,21 +89,15 @@ void TaskResolver::update(ezgl::application* app)
g_vpr_ctx.path_type = typePath; // duplicated
task.success(msg);
} else {
std::string msg = "bad options [" + task.options() + "] for get crit path list telegram";
std::string msg = "options errors in get crit path list telegram: " + options.errorsStr();
std::cerr << msg << std::endl;
task.error(msg);
}
} else if (task.cmd() == CMD_DRAW_PATH_ID) {
if (optionsList.size() == 2) {
int pathIndex = telegramparser::extractPathIndex(optionsList[0]) - 1;
int highLightMode = 1;

try {
highLightMode = std::atoi(optionsList[1].c_str());
} catch(...) {

}

options.validateNamePresence({OPTION_PATH_INDEX, OPTION_HIGHTLIGHT_MODE});
int pathIndex = options.getInt(OPTION_PATH_INDEX, -1);
int highLightMode = options.getInt(OPTION_HIGHTLIGHT_MODE, 1);
if (!options.hasErrors()) {
if ((pathIndex >= 0) && (pathIndex < g_vpr_ctx.crit_paths.size())) {
g_vpr_ctx.crit_path_index = pathIndex;

Expand All @@ -117,7 +111,7 @@ void TaskResolver::update(ezgl::application* app)
task.error(msg);
}
} else {
std::string msg = "bad options [" + task.options() + "] for highlight crit path telegram";
std::string msg = "options errors in highlight crit path telegram: " + options.errorsStr();
std::cerr << msg << std::endl;
task.error(msg);
}
Expand Down
115 changes: 115 additions & 0 deletions vpr/src/server/telegramoptions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#pragma once

#include <sstream>
#include <iostream>
#include <set>
#include <vector>
#include <unordered_map>

class TelegramOptions {
private:
enum {
INDEX_TYPE=0,
INDEX_NAME,
INDEX_VALUE,
TOTAL_INDEXES_NUM
};

struct Option {
std::string type;
std::string value;
};

public:
TelegramOptions(const std::string& data) {
std::vector<std::string> options = splitString(data, ';');
for (const std::string& optionStr: options) {
std::vector<std::string> fragments = splitString(optionStr, ':');
if (fragments.size() == TOTAL_INDEXES_NUM) {
std::string name = fragments[INDEX_NAME];
Option option{fragments[INDEX_TYPE], fragments[INDEX_VALUE]};
if (validateType(option.type)) {
m_options[name] = option;
} else {
m_errors.emplace_back("bad type for option [" + optionStr + "]");
}
} else {
m_errors.emplace_back("bad option [" + optionStr + "]");
}
}
}

~TelegramOptions() {}

bool hasErrors() const { return !m_errors.empty(); }

bool validateNamePresence(const std::vector<std::string>& names) {
bool result = true;
for (const std::string& name: names) {
if (m_options.find(name) == m_options.end()) {
m_errors.emplace_back("cannot find required option " + name);
result = false;
}
}
return result;
}

std::string getString(const std::string& name) {
std::string result;
if (auto it = m_options.find(name); it != m_options.end()) {
result = it->second.value;
}
return result;
}

int getInt(const std::string& name, int defaultValue) {
int result = defaultValue;
try {
result = std::atoi(m_options[name].value.c_str());
} catch(...) {
m_errors.emplace_back("cannot get int value for option " + name);
}
return result;
}

bool getBool(const std::string& name, bool defaultValue) {
bool result = defaultValue;
try {
result = std::atoi(m_options[name].value.c_str());
} catch(...) {
m_errors.emplace_back("cannot get bool value for option " + name);
}
return result;
}

std::string errorsStr() const {
std::string result;
for (const std::string& error: m_errors) {
result += error + ";";
}
return result;
}

private:
std::unordered_map<std::string, Option> m_options;
std::vector<std::string> m_errors;


std::vector<std::string> splitString(const std::string& input, char delimiter)
{
std::vector<std::string> tokens;
std::istringstream tokenStream(input);
std::string token;

while (std::getline(tokenStream, token, delimiter)) {
tokens.push_back(token);
}

return tokens;
}

bool validateType(const std::string& type) {
static std::set<std::string> supportedTypes{"int", "string", "bool"};
return supportedTypes.count(type) != 0;
}
};
18 changes: 3 additions & 15 deletions vpr/src/server/telegramparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace telegramparser {

int extractJobId(const std::string& message)
{
std::regex pattern("\"JOB_ID\":(\\d+)");
static std::regex pattern("\"JOB_ID\":(\\d+)");
std::smatch match;
if (std::regex_search(message, match, pattern)) {
if (match.size() > 1) {
Expand All @@ -18,7 +18,7 @@ int extractJobId(const std::string& message)

int extractCmd(const std::string& message)
{
std::regex pattern("\"CMD\":(\\d+)");
static std::regex pattern("\"CMD\":(\\d+)");
std::smatch match;
if (std::regex_search(message, match, pattern)) {
if (match.size() > 1) {
Expand All @@ -30,7 +30,7 @@ int extractCmd(const std::string& message)

std::string extractOptions(const std::string& message)
{
std::regex pattern("\"OPTIONS\":\"(.*?)\"");
static std::regex pattern("\"OPTIONS\":\"(.*?)\"");
std::smatch match;
if (std::regex_search(message, match, pattern)) {
if (match.size() > 1) {
Expand All @@ -40,16 +40,4 @@ std::string extractOptions(const std::string& message)
return "";
}

int extractPathIndex(const std::string& message)
{
std::regex pattern("^#Path (\\d+)");
std::smatch match;
if (std::regex_search(message, match, pattern)) {
if (match.size() > 1) {
return std::atoi(match[1].str().c_str());
}
}
return -1;
}

} // telegramparser
1 change: 0 additions & 1 deletion vpr/src/server/telegramparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ namespace telegramparser {
int extractJobId(const std::string& message);
int extractCmd(const std::string& message);
std::string extractOptions(const std::string& message);
int extractPathIndex(const std::string& message);

} // telegramparser

Expand Down

0 comments on commit 22bbf9c

Please sign in to comment.