diff --git a/Core/Messages/messagefield.cpp b/Core/Messages/messagefield.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0fab7dfa84bc16a2a87b655ccc8cec61ee4b698d --- /dev/null +++ b/Core/Messages/messagefield.cpp @@ -0,0 +1,95 @@ +#include "messagefield.h" + +MessageField::MessageField() : type(Type::EMPTY) { } + +MessageField::MessageField(int64_t _i64) : type(Type::INTEGER), i64(_i64) {} +MessageField::MessageField(uint64_t _u64) : type(Type::UINTEGER), u64(_u64) {} +MessageField::MessageField(double _d) : type(Type::DOUBLE), d(_d) {} +MessageField::MessageField(char _c) : type(Type::CHAR), c(_c) {} +MessageField::MessageField(QString _s) : type(Type::STRING), s(_s) {} + +int64_t MessageField::getInteger(int64_t defaultValue) const { + if(type == Type::INTEGER) { + return i64; + } else { + return defaultValue; + } +} + +uint64_t MessageField::getUInteger(uint64_t defaultValue) const { + if(type == Type::UINTEGER) { + return u64; + } else { + return defaultValue; + } +} + +double MessageField::getDouble(double defaultValue) const { + if(type == Type::DOUBLE) { + return d; + } else { + return defaultValue; + } +} + +char MessageField::getChar(char defaultValue) const { + if(type == Type::CHAR) { + return c; + } else { + return defaultValue; + } +} + +QString MessageField::getString() const { + switch(type) { + case Type::EMPTY: + return QString(); + case Type::INTEGER: + return QString::number(i64); + case Type::UINTEGER: + return QString::number(u64); + case Type::DOUBLE: + return QString::number(d); + case Type::CHAR: + return QString(c); + case Type::STRING: + return s; + } +} + +void MessageField::set(int64_t value) { + type = Type::INTEGER; + i64 = value; +} + +void MessageField::set(uint64_t value) { + type = Type::UINTEGER; + u64 = value; +} + +void MessageField::set(double value) { + type = Type::DOUBLE; + d = value; +} + +void MessageField::set(char value) { + type = Type::CHAR; + c = value; +} + +void MessageField::set(QString value) { + type = Type::STRING; + s = value; +} + +void MessageField::set() { + if(type == Type::STRING) { + s.clear(); + } + + type = Type::EMPTY; +} + +MessageField::Type MessageField::getType() const { + return type; +} diff --git a/Core/Messages/messagefield.h b/Core/Messages/messagefield.h new file mode 100644 index 0000000000000000000000000000000000000000..c00dd65064c41a1616b652f27cf614768930e19c --- /dev/null +++ b/Core/Messages/messagefield.h @@ -0,0 +1,52 @@ +#ifndef MESSAGEFIELD_H +#define MESSAGEFIELD_H + +#include <QString> +#include <cstdint> + +class MessageField { + public: + enum class Type { + EMPTY, + INTEGER, + UINTEGER, + DOUBLE, + CHAR, + STRING + }; + + MessageField(); + MessageField(int64_t _i64); + MessageField(uint64_t _u64); + MessageField(double _d); + MessageField(char _c); + MessageField(QString _s); + + int64_t getInteger(int64_t defaultValue) const; + uint64_t getUInteger(uint64_t defaultValue) const; + double getDouble(double defaultValue) const; + char getChar(char defaultValue) const; + QString getString() const; + + void set(int64_t value); + void set(uint64_t value); + void set(double value); + void set(char value); + void set(QString value); + void set(); + + Type getType() const; + + private: + Type type; + QString s; + + union { + int64_t i64; + uint64_t u64; + double d; + char c; + }; +}; + +#endif // MESSAGEFIELD_H diff --git a/Core/Messages/topic.cpp b/Core/Messages/topic.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7fee1b57267dfb5221c29be6ef064d290bd7e219 --- /dev/null +++ b/Core/Messages/topic.cpp @@ -0,0 +1,40 @@ +#include "topic.h" + +#include <QRegExp> + +Topic::Topic(QString str) { + if(str == "*" || str.contains(QRegExp("^[A-Za-z0-9$_]+(/[A-Za-z0-9$_]+)*(/*)?$"))) { + repr = str; + } else { + str = "Invalid"; + } +} + +bool Topic::match(Topic prefix) const { + if(prefix.repr.endsWith("*")) { + int prefixSize = prefix.repr.size() - 2; + return repr.size() >= prefixSize && repr.at(prefixSize - 1) == '/' && repr.startsWith(prefix.repr.leftRef(prefixSize)); + } else { + return repr == prefix.repr; + } +} + +Topic Topic::getParent() const { + int idx = repr.lastIndexOf('/'); + return idx == -1 ? Topic(repr) : Topic(repr.left(idx)); +} + +Topic Topic::getRoot() const { + int idx = repr.indexOf('/'); + return idx == -1 ? Topic(repr) : Topic(repr.left(idx)); +} + +QString Topic::toString() const { + return repr; +} + +bool Topic::isWildcard() const { + return repr.contains('*'); +} + +static const Topic Any("*"); diff --git a/Core/Messages/topic.h b/Core/Messages/topic.h new file mode 100644 index 0000000000000000000000000000000000000000..efd658519cc27f833ec4bbb5488cda81321bbed9 --- /dev/null +++ b/Core/Messages/topic.h @@ -0,0 +1,40 @@ +#ifndef TOPIC_H +#define TOPIC_H + +#include <QString> + +/* + * This class defines topics for GS messages. + * + * Topics are strings made of alphanumerical characters and slashes '/'. For example, + * "Prefix/Section2/Message" and "SomeMessage" are valid topics. I'll call the parts + * between slashes tokens. + * + * When a Module subscribes to a topic, it is allowed to specify a wildcard topic, which + * uses as last token a *, so that it will match against all topics with the same prefix. + * + * For example: "Prefix/*" is a valid topic that matches against "Prefix", "Prefix/AMessage" and + * "Prefix/Section2/Message". Similarly, "*" will match against anything. + * +*/ + +class Topic { + private: + QString repr; + + public: + Topic(QString str); + + bool match(Topic prefix) const; + bool match(QString prefix) const; + + Topic getParent() const; + Topic getRoot() const; + + QString toString() const; + bool isWildcard() const; + + static const Topic Any; +}; + +#endif // TOPIC_H diff --git a/Core/modulemessage.h b/Core/modulemessage.h index ef0d923248297549bc59a59955ea25cd8227d3ef..a5f5f14dcc8d9cf7128cc956c38d61adad0f0a0c 100644 --- a/Core/modulemessage.h +++ b/Core/modulemessage.h @@ -9,49 +9,49 @@ class ModuleMessage { public: ModuleMessage(); - ModuleMessage(const QString &topic); - ModuleMessage(const QString &_topic, const QString &payload); - ModuleMessage(const QString &_topic, const QString &payload, const QTime &time); - ModuleMessage(const ModuleMessage &other); + ModuleMessage(const QString& topic); + ModuleMessage(const QString& _topic, const QString& payload); + ModuleMessage(const QString& _topic, const QString& payload, const QTime& time); + ModuleMessage(const ModuleMessage& other); - ModuleMessage operator=(const ModuleMessage &other); + ModuleMessage operator=(const ModuleMessage& other); QString payload() const; - void setPayload(const QString &value); + void setPayload(const QString& value); void setPayload(int value); QString topic() const; - void setTopic(const QString &value); + void setTopic(const QString& value); QTime timestamp() const; - void setTimestamp(const QTime ×tamp); + void setTimestamp(const QTime& timestamp); QString getHigherHierarchyTopic() const; QString originalTopic() const; - void setOriginalTopic(const QString &originalTopic); + void setOriginalTopic(const QString& originalTopic); /* * Returns an XmlObject containing some options */ XmlObject getOptions() const; - QString getOption(const QString &optionName) const; - bool getIntOption(const QString &optionName, int &val) const; - void setOptions(const XmlObject &value); - void addOption(const QString &optionName, const QString &value); - void addOption(const QString &optionName, int value); + QString getOption(const QString& optionName) const; + bool getIntOption(const QString& optionName, int& val) const; + void setOptions(const XmlObject& value); + void addOption(const QString& optionName, const QString& value); + void addOption(const QString& optionName, int value); /* * Get the value of "value" if the payload exist and is an integer */ - bool getIntPayload(int &value) const; + bool getIntPayload(int& value) const; - bool getFloatPayload(float &value) const; + bool getFloatPayload(float& value) const; QString toString() const; private: - void copy(const ModuleMessage &msg); + void copy(const ModuleMessage& msg); QString _payload; QString _topic; diff --git a/SkywardHub.pro b/SkywardHub.pro index b6275d7484efdba0f2001ec20a40c6abd150db7b..38fe58297b12d224dace02eddd1d2647f7cc3ee9 100644 --- a/SkywardHub.pro +++ b/SkywardHub.pro @@ -17,6 +17,8 @@ SOURCES += \ Components/ToggleButton/togglebutton.cpp \ Components/ErrorDisplayer/error.cpp \ Components/ErrorDisplayer/errordisplayer.cpp \ + Core/Messages/messagefield.cpp \ + Core/Messages/topic.cpp \ Core/module.cpp \ Core/moduleeventshandler.cpp \ Core/modulemessage.cpp \ @@ -73,6 +75,8 @@ HEADERS += \ Components/ToggleButton/togglebutton.h \ Components/ErrorDisplayer/error.h \ Components/ErrorDisplayer/errordisplayer.h \ + Core/Messages/messagefield.h \ + Core/Messages/topic.h \ Core/module.h \ Core/moduleeventshandler.h \ Core/modulemessage.h \