Skip to content
Snippets Groups Projects
Commit 1460f1ba authored by Alberto Nidasio's avatar Alberto Nidasio Committed by Emilio Corigliano
Browse files

[Topic][Filter] Fixed topics matching when wildcard is involved

The correct behaviour is this:
- `*/In/*` and `Main/In/PING_TM` matches
- `*/Out/*` and `Main/In/PING_TM` does not

Previously, the wildcard was only used for the whole topic
parent 3f4e2009
No related branches found
No related tags found
1 merge request!33Draft: [Topics] Added support for multiple concurrent target systems
......@@ -18,66 +18,67 @@
#include "Topic.h"
#include <qchar.h>
#include <qglobal.h>
#include <QDebug>
#include <QRegExp>
Topic::Topic() : topic("") {}
Topic::Topic() : string("") {}
Topic::Topic(QString topic) : topic(topic) {}
Topic::Topic(QString topic) : string(topic)
{
if (!isValid())
qWarning() << "Invalid topic created: " << topic;
}
bool Topic::operator==(const Topic& toCompare) const
{
// Always true if the current topic is a pure wildcard
if (topic == "*" || topic == "?")
// Always true if one of the topics is a pure wildcard
if (string == "*" || toCompare.string == "*")
return true;
// If the current topic isn't a wildcard then the topic must match
if (!isWildcard())
return topic == toCompare.toString();
// If the topics are equal, return true
if (string == toCompare.string)
return true;
// If the current topic is a wildcard then only the prefix must match
return toCompare.toString().startsWith(getPrefix().toString());
}
auto our_stripped = stripRoot();
auto their_stripped = toCompare.stripRoot();
bool Topic::operator<(const Topic& toCompare) const
{
return topic < toCompare.topic;
}
// If one of them is a root topic, they must be different, since we already
// checked for equality
if (!our_stripped.has_value() || !their_stripped.has_value())
return false;
Topic Topic::getParent() const
{
int idx = topic.lastIndexOf('/');
return idx == -1 ? Topic(topic) : Topic(topic.left(idx));
// Otherwise, the roots and the stripped topics must be equal. Also, one of
// the stripped topics must not be null
return root() == toCompare.root() && our_stripped == their_stripped &&
(our_stripped.has_value() || their_stripped.has_value());
}
Topic Topic::getRoot() const
Topic Topic::root() const
{
int idx = topic.indexOf('/');
return idx == -1 ? Topic(topic) : Topic(topic.left(idx));
}
int idx = string.indexOf('/');
Topic Topic::getPrefix() const
{
if (!isWildcard())
if (idx == -1)
return *this;
int idxAst = topic.lastIndexOf('*');
int idxQue = topic.lastIndexOf('?');
int idx = idxAst != -1 ? idxAst : idxQue;
return Topic(topic.left(idx));
else
return Topic(string.left(idx));
}
bool Topic::isValid() const
std::optional<Topic> Topic::stripRoot() const
{
return topic.contains(QRegExp("^[A-Za-z0-9$_]+(\\/[A-Za-z0-9$_]+)*$"));
int idx = string.indexOf('/');
if (idx == -1)
return std::nullopt;
else
return Topic(string.right(string.length() - idx - 1));
}
bool Topic::isWildcard() const
bool Topic::isValid() const
{
// Check wether the last character is a wildcard
return topic.at(topic.size() - 1) == '*' ||
topic.at(topic.size() - 1) == '?';
return string.contains(QRegExp("^([\\w\\d*]+\\/)*[\\w\\d_*]*$"));
}
QString Topic::toString() const { return topic; }
QString Topic::toString() const { return string; }
......@@ -18,58 +18,48 @@
#pragma once
#include <qchar.h>
#include <QString>
#include <optional>
/**
* @brief Topics are strings made of alphanumerical characters and slashes '/'.
*
* For example, "Prefix/Message" and "SomeMessage" are valid topics.
* For example, "Main/In/<asterix>", "SomeMessage", "*" are valid topics.
*/
class Topic
class Topic : QString
{
public:
Topic();
explicit Topic(QString topic);
/**
* @brief Check if the given topic matches, also if the current is a
* wildcard.
* @brief Check if the given topic matches, considering wildcards.
*/
bool operator==(const Topic& toCompare) const;
bool operator<(const Topic& toCompare) const;
/**
* @brief Returns the parent.
*
* If the topic is Prefix/Message, returns Prefix.
*/
Topic getParent() const;
/**
* @brief Returns the topic root.
*
* If the topic is Topic/SubTopic/SubSubTopic, returns Topic.
* @brief True if the topic is valid.
*/
Topic getRoot() const;
bool isValid() const;
/**
* @brief Removes the wildcard from a wildcard topic.
*/
Topic getPrefix() const;
QString toString() const;
private:
/**
* @brief True if the topic is valid.
* @brief Get the root of the topic.
*
* For example, the root of "Main/In/<asterix>" is "Main".
*/
bool isValid() const;
Topic root() const;
/**
* @brief Returns true if the topic is a wildcard.
* @brief Strip the root of the topic.
*
* For example, the root of "Main/In/<asterix>" is "In/<asterix>".
*/
bool isWildcard() const;
std::optional<Topic> stripRoot() const;
QString toString() const;
private:
QString topic;
QString string;
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment