mqttauditing/mqtttopicmatcher.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;
}
}
}