utils.cpp
3.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "utils.h"
std::list<std::__cxx11::string> split(const std::string &input, const char sep, size_t max, bool keep_empty_parts)
{
std::list<std::string> list;
size_t start = 0;
size_t end;
while (list.size() < max && (end = input.find(sep, start)) != std::string::npos)
{
if (start != end || keep_empty_parts)
list.push_back(input.substr(start, end - start));
start = end + 1; // increase by length of seperator.
}
if (start != input.size() || keep_empty_parts)
list.push_back(input.substr(start, std::string::npos));
return list;
}
bool topicsMatch(const std::string &subscribeTopic, const std::string &publishTopic)
{
if (subscribeTopic.find("+") == std::string::npos && subscribeTopic.find("#") == std::string::npos)
return subscribeTopic == publishTopic;
const std::list<std::string> subscribeParts = split(subscribeTopic, '/');
const std::list<std::string> publishParts = split(publishTopic, '/');
auto subscribe_itr = subscribeParts.begin();
auto publish_itr = publishParts.begin();
bool result = true;
while (subscribe_itr != subscribeParts.end() && publish_itr != publishParts.end())
{
const std::string &subscribe_subtopic = *subscribe_itr++;
const std::string &publish_subtopic = *publish_itr++;
if (subscribe_subtopic == "+")
continue;
if (subscribe_subtopic == "#")
return true;
if (subscribe_subtopic != publish_subtopic)
return false;
}
result = subscribe_itr == subscribeParts.end() && publish_itr == publishParts.end();
return result;
}
bool isValidUtf8(const std::string &s)
{
int multibyte_remain = 0;
int cur_code_point = 0;
for(const char &x : s)
{
if (x == 0)
return false;
if(!multibyte_remain)
{
cur_code_point = 0;
if((x & 0b11100000) == 0b11000000) // 2 byte char
{
multibyte_remain = 1;
cur_code_point += ((x & 0b00011111) << 6);
}
else if((x & 0b11110000) == 0b11100000) // 3 byte char
{
multibyte_remain = 2;
cur_code_point += ((x & 0b00001111) << 12);
}
else if((x & 0b11111000) == 0b11110000) // 4 byte char
{
multibyte_remain = 3;
cur_code_point += ((x & 0b00000111) << 18);
}
else if((x & 0b10000000) != 0)
return false;
else
cur_code_point += (x & 0b01111111);
}
else // All remainer bytes of this code point needs to start with 10
{
if((x & 0b11000000) != 0b10000000)
return false;
multibyte_remain--;
cur_code_point += ((x & 0b00111111) << (6*multibyte_remain));
}
if (multibyte_remain == 0)
{
// Invalid range for MQTT. [MQTT-1.5.3-1]
if (cur_code_point >= 0xD800 && cur_code_point <= 0xDFFF) // Dec 55296-57343
return false;
if (cur_code_point >= 0x0001 && cur_code_point <= 0x001F)
return false;
if (cur_code_point >= 0x007F && cur_code_point <= 0x009F)
return false;
if (cur_code_point == 0xFFFF)
return false;
cur_code_point = 0;
}
}
return multibyte_remain == 0;
}
bool strContains(const std::string &s, const std::string &needle)
{
return s.find(needle) != std::string::npos;
}
bool isValidPublishPath(const std::string &s)
{
if (s.empty())
return false;
for (const char c : s)
{
if (c == '#' || c == '+')
return false;
}
return true;
}