Subscribe to all topics with '#'

Signed-off-by: Mariusz <mariusz.suchora@tieto.com>
This commit is contained in:
Mariusz
2018-03-06 10:55:40 +01:00
parent 9414410cce
commit e6a9fdca01
2 changed files with 153 additions and 36 deletions

View File

@@ -736,11 +736,6 @@ bool Topic::isMatch(string* topicName)
{ {
string::size_type tlen = _topicName->size(); string::size_type tlen = _topicName->size();
if (topicName->size() < tlen - 2)
{
return false;
}
string::size_type tpos = 0; string::size_type tpos = 0;
string::size_type tloc = 0; string::size_type tloc = 0;
string::size_type pos = 0; string::size_type pos = 0;
@@ -809,17 +804,22 @@ bool Topic::isMatch(string* topicName)
return false; return false;
} }
} }
else if ( loc != string::npos && tloc == string::npos ) else if ( loc == string::npos && tloc != string::npos )
{ {
tloc = _topicName->find('#', --tpos); string subtopic = topicName->substr(pos);
if ( tloc == string::npos ) string subtopict = _topicName->substr(tpos, tloc - tpos);
if ( subtopic != subtopict)
{ {
return false; return false;
} }
else
{ tpos = tloc + 1;
return true;
} return _topicName->substr(tpos) == wildcard;
}
else if ( loc != string::npos && tloc == string::npos )
{
return _topicName->substr(tpos) == wildcard;
} }
} }
} }
@@ -854,7 +854,8 @@ uint16_t Topics::getTopicId(const MQTTSN_topicid* topicid)
Topic* p = _first; Topic* p = _first;
while (p) while (p)
{ {
if (strncmp(p->_topicName->c_str(), topicid->data.long_.name, topicid->data.long_.len) == 0) if ( (int)strlen(p->_topicName->c_str()) == topicid->data.long_.len &&
strncmp(p->_topicName->c_str(), topicid->data.long_.name, topicid->data.long_.len) == 0)
{ {
return p->_topicId; return p->_topicId;
} }
@@ -882,7 +883,8 @@ Topic* Topics::getTopic(const MQTTSN_topicid* topicid)
Topic* p = _first; Topic* p = _first;
while (p) while (p)
{ {
if (strncmp(p->_topicName->c_str(), topicid->data.long_.name, topicid->data.long_.len) == 0 ) if ( (int)strlen(p->_topicName->c_str()) == topicid->data.long_.len &&
strncmp(p->_topicName->c_str(), topicid->data.long_.name, topicid->data.long_.len) == 0 )
{ {
return p; return p;
} }

View File

@@ -12,6 +12,7 @@
* *
* Contributors: * Contributors:
* Tomoaki Yamaguchi - initial API and implementation * Tomoaki Yamaguchi - initial API and implementation
* Tieto Poland Sp. z o.o. - Topic test improvements
**************************************************************************************/ **************************************************************************************/
#include <stdlib.h> #include <stdlib.h>
@@ -32,12 +33,55 @@ TestTopics::~TestTopics()
delete _topics; delete _topics;
} }
bool testIsMatch(const char* topicFilter, const char* topicName)
{
string* filter = new string(topicFilter);
string* name = new string(topicName);
Topic topic(filter);
bool isMatch = topic.isMatch(name);
delete name;
return isMatch;
}
bool testGetTopic(const char* topicName, const char* searchedTopicName)
{
Topics topics;
string name(topicName);
MQTTSN_topicid topicid;
topicid.type = MQTTSN_TOPIC_TYPE_NORMAL;
topicid.data.long_.len = strlen(searchedTopicName);
topicid.data.long_.name = const_cast<char*>(searchedTopicName);
topics.add(&name);
return topics.getTopic(&topicid) != 0;
}
bool testGetTopicId(const char* topicName, const char* searchedTopicName)
{
Topics topics;
string name(topicName);
MQTTSN_topicid topicid;
topicid.type = MQTTSN_TOPIC_TYPE_NORMAL;
topicid.data.long_.len = strlen(searchedTopicName);
topicid.data.long_.name = const_cast<char*>(searchedTopicName);
topics.add(&name);
return topics.getTopicId(&topicid) != 0;
}
void TestTopics::test(void) void TestTopics::test(void)
{ {
printf("Test Topics "); printf("Test Topics ");
MQTTSN_topicid topic[12]; const int TOPIC_COUNT = 13;
char tp[12][10];
MQTTSN_topicid topic[TOPIC_COUNT];
char tp[TOPIC_COUNT][10];
/* create Topic */ /* create Topic */
strcpy(tp[0], "Topic/+"); strcpy(tp[0], "Topic/+");
@@ -48,13 +92,12 @@ void TestTopics::test(void)
for ( int i = 1; i < 10 ; i++ ) for ( int i = 1; i < 10 ; i++ )
{ {
strcpy(tp[i], "Topic/+/"); sprintf(tp[i], "Topic/+/%d", i);
tp[i][8] = 0x30 + i;
tp[i][9] = 0;
topic[i].type = MQTTSN_TOPIC_TYPE_NORMAL; topic[i].type = MQTTSN_TOPIC_TYPE_NORMAL;
topic[i].data.long_.len = strlen(tp[i]); topic[i].data.long_.len = strlen(tp[i]);
topic[i].data.long_.name = tp[i]; topic[i].data.long_.name = tp[i];
} }
strcpy(tp[10], "TOPIC/#"); strcpy(tp[10], "TOPIC/#");
tp[10][7] = 0; tp[10][7] = 0;
topic[10].type = MQTTSN_TOPIC_TYPE_NORMAL; topic[10].type = MQTTSN_TOPIC_TYPE_NORMAL;
@@ -67,8 +110,14 @@ void TestTopics::test(void)
topic[11].data.long_.len = strlen(tp[11]); topic[11].data.long_.len = strlen(tp[11]);
topic[11].data.long_.name = tp[11]; topic[11].data.long_.name = tp[11];
tp[12][0] = '#';
tp[12][1] = 0;
topic[12].type = MQTTSN_TOPIC_TYPE_NORMAL;
topic[12].data.long_.len = strlen(tp[12]);
topic[12].data.long_.name = tp[12];
/* Add Topic to Topics */ /* Add Topic to Topics */
for ( int i = 0; i < 12; i++ ) for ( int i = 0; i < TOPIC_COUNT; i++ )
{ {
MQTTSN_topicid pos = topic[i]; MQTTSN_topicid pos = topic[i];
Topic* t = _topics->add(&pos); Topic* t = _topics->add(&pos);
@@ -86,7 +135,7 @@ void TestTopics::test(void)
} }
/* Get Topic by MQTTSN_topicid */ /* Get Topic by MQTTSN_topicid */
for ( int i = 0; i < 12; i++ ) for ( int i = 0; i < TOPIC_COUNT; i++ )
{ {
Topic* t = _topics->getTopic(&topic[i]); Topic* t = _topics->getTopic(&topic[i]);
//printf("Topic=%s ID=%d ID=%d\n", t->getTopicName()->c_str(), t->getTopicId(),_topics->getTopicId(&topic[i])); //printf("Topic=%s ID=%d ID=%d\n", t->getTopicName()->c_str(), t->getTopicId(),_topics->getTopicId(&topic[i]));
@@ -94,23 +143,19 @@ void TestTopics::test(void)
} }
/* Get TopicId by MQTTSN_topicid */ /* Get TopicId by MQTTSN_topicid */
for ( int i = 0; i < 12; i++ ) for ( int i = 0; i < TOPIC_COUNT; i++ )
{ {
uint16_t id = _topics->getTopicId(&topic[i]); uint16_t id = _topics->getTopicId(&topic[i]);
//printf("ID=%d \n", id); //printf("ID=%d \n", id);
assert(id == i + 1); assert(id == i + 1);
} }
/* Test Wilecard */ /* Test Wildcard */
for ( int i = 0; i < 10 ; i++ ) for ( int i = 0; i < 10 ; i++ )
{ {
MQTTSN_topicid tp1; MQTTSN_topicid tp1;
char tp0[10]; char tp0[10];
strcpy(tp0, "Topic/"); sprintf(tp0, "Topic/%d/%d", i, i);
tp0[6] = 0x30 + i;
tp0[7] = '/';
tp0[8] = 0x30 + i;
tp0[9] = 0;
tp1.type = MQTTSN_TOPIC_TYPE_NORMAL; tp1.type = MQTTSN_TOPIC_TYPE_NORMAL;
tp1.data.long_.len = strlen(tp0); tp1.data.long_.len = strlen(tp0);
tp1.data.long_.name = tp0; tp1.data.long_.name = tp0;
@@ -128,13 +173,12 @@ void TestTopics::test(void)
*/ */
assert(t != 0); assert(t != 0);
} }
for ( int i = 0; i < 10 ; i++ ) for ( int i = 0; i < 10 ; i++ )
{ {
MQTTSN_topicid tp1; MQTTSN_topicid tp1;
char tp0[10]; char tp0[10];
strcpy(tp0, "Topic/"); sprintf(tp0, "Topic/%d", i);
tp0[6] = 0x30 + i;
tp0[7] = 0;
tp1.type = MQTTSN_TOPIC_TYPE_NORMAL; tp1.type = MQTTSN_TOPIC_TYPE_NORMAL;
tp1.data.long_.len = strlen(tp0); tp1.data.long_.len = strlen(tp0);
tp1.data.long_.name = tp0; tp1.data.long_.name = tp0;
@@ -151,17 +195,14 @@ void TestTopics::test(void)
} }
*/ */
assert(t != 0); assert(t != 0);
assert(t->getTopicName()->compare(tp[0]) == 0);
} }
for ( int i = 0; i < 10 ; i++ ) for ( int i = 0; i < 10 ; i++ )
{ {
MQTTSN_topicid tpid1; MQTTSN_topicid tpid1;
char tp0[10]; char tp0[10];
strcpy(tp0, "TOPIC/"); sprintf(tp0, "TOPIC/%d/%d", i, i);
tp0[6] = 0x30 + i;
tp0[7] = '/';
tp0[8] = 0x30 + i;
tp0[9] = 0;
tpid1.type = MQTTSN_TOPIC_TYPE_NORMAL; tpid1.type = MQTTSN_TOPIC_TYPE_NORMAL;
tpid1.data.long_.len = strlen(tp0); tpid1.data.long_.len = strlen(tp0);
tpid1.data.long_.name = tp0; tpid1.data.long_.name = tp0;
@@ -178,6 +219,80 @@ void TestTopics::test(void)
} }
*/ */
assert( t != 0); assert( t != 0);
assert(t->getTopicName()->compare(tp[10]) == 0);
} }
{
MQTTSN_topicid tp1;
char tp0[10];
strcpy(tp0, "Topic");
tp1.type = MQTTSN_TOPIC_TYPE_NORMAL;
tp1.data.long_.len = strlen(tp0);
tp1.data.long_.name = tp0;
Topic* t = _topics->match(&tp1);
assert(t != 0);
assert(t->getTopicName()->compare(tp[12]) == 0);
}
{
MQTTSN_topicid tp1;
char tp0[20];
strcpy(tp0, "Topic/multi/level");
tp1.type = MQTTSN_TOPIC_TYPE_NORMAL;
tp1.data.long_.len = strlen(tp0);
tp1.data.long_.name = tp0;
Topic* t = _topics->match(&tp1);
assert(t != 0);
assert(t->getTopicName()->compare(tp[12]) == 0);
}
assert(testIsMatch("#", "one"));
assert(testIsMatch("#", "one/"));
assert(testIsMatch("#", "one/two"));
assert(testIsMatch("#", "one/two/"));
assert(testIsMatch("#", "one/two/three"));
assert(testIsMatch("#", "one/two/three/"));
assert(!testIsMatch("one/+", "one"));
assert(testIsMatch("one/+", "one/"));
assert(testIsMatch("one/+", "one/two"));
assert(!testIsMatch("one/+", "one/two/"));
assert(!testIsMatch("one/+", "one/two/three"));
assert(!testIsMatch("one/+/three/+", "one/two/three"));
assert(testIsMatch("one/+/three/+", "one/two/three/"));
assert(testIsMatch("one/+/three/+", "one/two/three/four"));
assert(!testIsMatch("one/+/three/+", "one/two/three/four/"));
assert(testIsMatch("one/+/three/#", "one/two/three"));
assert(testIsMatch("one/+/three/#", "one/two/three/"));
assert(testIsMatch("one/+/three/#", "one/two/three/four"));
assert(testIsMatch("one/+/three/#", "one/two/three/four/"));
assert(testIsMatch("one/+/three/#", "one/two/three/four/five"));
// examples from MQTT specification
assert(testIsMatch("sport/tennis/player1/#", "sport/tennis/player1"));
assert(testIsMatch("sport/tennis/player1/#", "sport/tennis/player1/ranking"));
assert(testIsMatch("sport/tennis/player1/#", "sport/tennis/player1/score/wimbledon"));
assert(testIsMatch("sport/tennis/+", "sport/tennis/player1"));
assert(testIsMatch("sport/tennis/+", "sport/tennis/player2"));
assert(!testIsMatch("sport/tennis/+", "sport/tennis/player1/ranking"));
assert(testIsMatch("+/+", "/finance"));
assert(testIsMatch("/+", "/finance"));
assert(!testIsMatch("+", "/finance"));
assert(testGetTopicId("mytopic", "mytopic"));
assert(!testGetTopicId("mytopic", "mytop"));
assert(!testGetTopicId("mytopic", "mytopiclong"));
assert(testGetTopic("mytopic", "mytopic"));
assert(!testGetTopic("mytopic", "mytop"));
assert(!testGetTopic("mytopic", "mytopiclong"));
printf("[ OK ]\n"); printf("[ OK ]\n");
} }