119 lines
3.0 KiB
C
119 lines
3.0 KiB
C
#include <stdint.h>
|
|
#include "mqtttopicmatcher.h"
|
|
|
|
|
|
int cmpTopicWithWildcard(char *subscribedTopic, char *receivedTopic) {
|
|
uint32_t s_idx = 0;
|
|
uint32_t r_idx = 0;
|
|
char s;
|
|
char r;
|
|
|
|
enum { e_START, e_PART, e_DELIMITER, e_WAIT_FOR_DELIMITER_IN_S, e_WAIT_FOR_DELIMITER_IN_R } state;
|
|
state = e_START;
|
|
|
|
enum { r_NOK = -1, r_OK = 0, r_INVALID = 99 } res;
|
|
res = r_INVALID;
|
|
|
|
while (1) {
|
|
s = *(subscribedTopic + s_idx);
|
|
r = *(receivedTopic + r_idx);
|
|
|
|
if ((s == 0) && (r == 0) && (state == e_PART)) {
|
|
return 0;
|
|
}
|
|
|
|
switch (state) {
|
|
case e_START:
|
|
if (s == '#') {
|
|
res = r_OK;
|
|
break;
|
|
} else if (s == '+') {
|
|
state = e_WAIT_FOR_DELIMITER_IN_S;
|
|
s_idx++;
|
|
r_idx++;
|
|
break;
|
|
} else if (s == '/') {
|
|
state = e_DELIMITER;
|
|
s_idx++;
|
|
r_idx++;
|
|
break;
|
|
} else if (s == r) {
|
|
state = e_PART;
|
|
s_idx++;
|
|
r_idx++;
|
|
break;
|
|
} else {
|
|
res = r_NOK;
|
|
break;
|
|
}
|
|
case e_DELIMITER:
|
|
if (s == '#') {
|
|
res = r_OK;
|
|
break;
|
|
} else if (s == '+') {
|
|
state = e_WAIT_FOR_DELIMITER_IN_S;
|
|
s_idx++;
|
|
r_idx++;
|
|
break;
|
|
} else if (s == r) {
|
|
state = e_PART;
|
|
s_idx++;
|
|
r_idx++;
|
|
break;
|
|
} else {
|
|
res = r_NOK;
|
|
break;
|
|
}
|
|
case e_WAIT_FOR_DELIMITER_IN_S:
|
|
if (s != '/') {
|
|
res = r_NOK;
|
|
break;
|
|
} else if ((s == '/') && (r == '/')) {
|
|
state = e_PART;
|
|
s_idx++;
|
|
r_idx++;
|
|
break;
|
|
} else if ((s == '/') && (r != '/')) {
|
|
state = e_WAIT_FOR_DELIMITER_IN_R;
|
|
r_idx++;
|
|
break;
|
|
} else {
|
|
res = r_NOK;
|
|
break;
|
|
}
|
|
case e_WAIT_FOR_DELIMITER_IN_R:
|
|
if (r == '/') {
|
|
state = e_PART;
|
|
s_idx++;
|
|
r_idx++;
|
|
break;
|
|
} else {
|
|
r_idx++;
|
|
break;
|
|
}
|
|
case e_PART:
|
|
if (s == '#') {
|
|
res = r_OK;
|
|
break;
|
|
} else if (s == '+') {
|
|
state = e_WAIT_FOR_DELIMITER_IN_S;
|
|
s_idx++;
|
|
r_idx++;
|
|
break;
|
|
} else if (s == r) {
|
|
state = e_PART;
|
|
s_idx++;
|
|
r_idx++;
|
|
break;
|
|
} else {
|
|
res = r_NOK;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (res != r_INVALID) {
|
|
return res;
|
|
}
|
|
}
|
|
}
|