Browse Source

Refactor TopicFilterComparer

release/3.x.x
Christian 6 years ago
parent
commit
8077d8dfeb
2 changed files with 51 additions and 49 deletions
  1. +2
    -2
      Frameworks/MQTTnet.NetStandard/Server/MqttClientSessionsManager.cs
  2. +49
    -47
      Frameworks/MQTTnet.NetStandard/Server/MqttTopicFilterComparer.cs

+ 2
- 2
Frameworks/MQTTnet.NetStandard/Server/MqttClientSessionsManager.cs View File

@@ -136,9 +136,9 @@ namespace MQTTnet.Server
return Task.FromResult((IList<IMqttClientSessionStatus>)result);
}

public Task StartDispatchApplicationMessage(MqttClientSession senderClientSession, MqttApplicationMessage applicationMessage)
public void StartDispatchApplicationMessage(MqttClientSession senderClientSession, MqttApplicationMessage applicationMessage)
{
return DispatchApplicationMessageAsync(senderClientSession, applicationMessage);
Task.Run(() => DispatchApplicationMessageAsync(senderClientSession, applicationMessage));
}

public Task SubscribeAsync(string clientId, IList<TopicFilter> topicFilters)


+ 49
- 47
Frameworks/MQTTnet.NetStandard/Server/MqttTopicFilterComparer.cs View File

@@ -4,114 +4,116 @@ namespace MQTTnet.Server
{
public static class MqttTopicFilterComparer
{
private const char LEVEL_SEPARATOR = '/';
private const char WILDCARD_MULTI_LEVEL = '#';
private const char WILDCARD_SINGLE_LEVEL = '+';
private const char LevelSeparator = '/';
private const char MultiLevelWildcard = '#';
private const char SingleLevelWildcard = '+';

public static bool IsMatch(string topic, string filter)
{
if (string.IsNullOrEmpty(topic)) throw new ArgumentNullException(nameof(topic));
if (string.IsNullOrEmpty(filter)) throw new ArgumentNullException(nameof(filter));

int spos = 0;
int slen = filter.Length;
int tpos = 0;
int tlen = topic.Length;
var sPos = 0;
var sLen = filter.Length;
var tPos = 0;
var tLen = topic.Length;

while (spos < slen && tpos < tlen)
while (sPos < sLen && tPos < tLen)
{
if (filter[spos] == topic[tpos])
if (filter[sPos] == topic[tPos])
{
if (tpos == tlen - 1)
if (tPos == tLen - 1)
{
/* Check for e.g. foo matching foo/# */
if (spos == slen - 3
&& filter[spos + 1] == LEVEL_SEPARATOR
&& filter[spos + 2] == WILDCARD_MULTI_LEVEL)
// Check for e.g. foo matching foo/#
if (sPos == sLen - 3
&& filter[sPos + 1] == LevelSeparator
&& filter[sPos + 2] == MultiLevelWildcard)
{
return true;
}
}
spos++;
tpos++;
if (spos == slen && tpos == tlen)

sPos++;
tPos++;

if (sPos == sLen && tPos == tLen)
{
return true;
}
else if (tpos == tlen && spos == slen - 1 && filter[spos] == WILDCARD_SINGLE_LEVEL)

if (tPos == tLen && sPos == sLen - 1 && filter[sPos] == SingleLevelWildcard)
{
if (spos > 0 && filter[spos - 1] != LEVEL_SEPARATOR)
if (sPos > 0 && filter[sPos - 1] != LevelSeparator)
{
// Invalid filter string
return false;
}
spos++;
return true;
}
}
else
{
if (filter[spos] == WILDCARD_SINGLE_LEVEL)
if (filter[sPos] == SingleLevelWildcard)
{
/* Check for bad "+foo" or "a/+foo" subscription */
if (spos > 0 && filter[spos - 1] != LEVEL_SEPARATOR)
// Check for bad "+foo" or "a/+foo" subscription
if (sPos > 0 && filter[sPos - 1] != LevelSeparator)
{
// Invalid filter string
return false;
}
/* Check for bad "foo+" or "foo+/a" subscription */
if (spos < slen - 1 && filter[spos + 1] != LEVEL_SEPARATOR)

// Check for bad "foo+" or "foo+/a" subscription
if (sPos < sLen - 1 && filter[sPos + 1] != LevelSeparator)
{
// Invalid filter string
return false;
}
spos++;
while (tpos < tlen && topic[tpos] != LEVEL_SEPARATOR)

sPos++;
while (tPos < tLen && topic[tPos] != LevelSeparator)
{
tpos++;
tPos++;
}
if (tpos == tlen && spos == slen)

if (tPos == tLen && sPos == sLen)
{
return true;
}
}
else if (filter[spos] == WILDCARD_MULTI_LEVEL)
else if (filter[sPos] == MultiLevelWildcard)
{
if (spos > 0 && filter[spos - 1] != LEVEL_SEPARATOR)
if (sPos > 0 && filter[sPos - 1] != LevelSeparator)
{
// Invalid filter string
return false;
}
if (spos + 1 != slen)

if (sPos + 1 != sLen)
{
// Invalid filter string
return false;
}
else
{
return true;
}

return true;
}
else
{
/* Check for e.g. foo/bar matching foo/+/# */
if (spos > 0
&& spos + 2 == slen
&& tpos == tlen
&& filter[spos - 1] == WILDCARD_SINGLE_LEVEL
&& filter[spos] == LEVEL_SEPARATOR
&& filter[spos + 1] == WILDCARD_MULTI_LEVEL)
// Check for e.g. foo/bar matching foo/+/#
if (sPos > 0
&& sPos + 2 == sLen
&& tPos == tLen
&& filter[sPos - 1] == SingleLevelWildcard
&& filter[sPos] == LevelSeparator
&& filter[sPos + 1] == MultiLevelWildcard)
{
return true;
}

return false;
}
}
}
if (tpos < tlen || spos < slen)
{
return false;
}

return false;
}


Loading…
Cancel
Save