1
+ # Copyright (c) 2017 Yotch <https://github.com/yoch>
2
+ #
3
+ # This file is dual licensed under the Eclipse Public License 1.0 and the
4
+ # Eclipse Distribution License 1.0 as described in the epl-v10 and edl-v10 files.
5
+ #
6
+ #
7
+ """
8
+ `matcher`
9
+ ====================================================================================
10
+
11
+ MQTT topic filter matcher from the Eclipse Project's Paho.MQTT.Python
12
+ https://github.com/eclipse/paho.mqtt.python/blob/master/src/paho/mqtt/matcher.py
13
+ * Author(s): Yotch (https://github.com/yoch)
14
+ """
15
+
1
16
class MQTTMatcher (object ):
2
17
"""Intended to manage topic filters including wildcards.
3
18
@@ -7,7 +22,7 @@ class MQTTMatcher(object):
7
22
some topic name."""
8
23
9
24
class Node (object ):
10
- __slots__ = " _children" , " _content"
25
+ __slots__ = ' _children' , ' _content'
11
26
12
27
def __init__ (self ):
13
28
self ._children = {}
@@ -20,15 +35,15 @@ def __setitem__(self, key, value):
20
35
"""Add a topic filter :key to the prefix tree
21
36
and associate it to :value"""
22
37
node = self ._root
23
- for sym in key .split ("/" ):
38
+ for sym in key .split ('/' ):
24
39
node = node ._children .setdefault (sym , self .Node ())
25
40
node ._content = value
26
41
27
42
def __getitem__ (self , key ):
28
43
"""Retrieve the value associated with some topic filter :key"""
29
44
try :
30
45
node = self ._root
31
- for sym in key .split ("/" ):
46
+ for sym in key .split ('/' ):
32
47
node = node ._children [sym ]
33
48
if node ._content is None :
34
49
raise KeyError (key )
@@ -41,25 +56,24 @@ def __delitem__(self, key):
41
56
lst = []
42
57
try :
43
58
parent , node = None , self ._root
44
- for k in key .split ("/" ):
45
- parent , node = node , node ._children [k ]
46
- lst .append ((parent , k , node ))
59
+ for k in key .split ('/' ):
60
+ parent , node = node , node ._children [k ]
61
+ lst .append ((parent , k , node ))
47
62
# TODO
48
63
node ._content = None
49
64
except KeyError :
50
65
raise KeyError (key )
51
66
else : # cleanup
52
67
for parent , k , node in reversed (lst ):
53
68
if node ._children or node ._content is not None :
54
- break
69
+ break
55
70
del parent ._children [k ]
56
71
57
72
def iter_match (self , topic ):
58
73
"""Return an iterator on all values associated with filters
59
74
that match the :topic"""
60
- lst = topic .split ("/" )
61
- normal = not topic .startswith ("$" )
62
-
75
+ lst = topic .split ('/' )
76
+ normal = not topic .startswith ('$' )
63
77
def rec (node , i = 0 ):
64
78
if i == len (lst ):
65
79
if node ._content is not None :
@@ -69,12 +83,11 @@ def rec(node, i=0):
69
83
if part in node ._children :
70
84
for content in rec (node ._children [part ], i + 1 ):
71
85
yield content
72
- if "+" in node ._children and (normal or i > 0 ):
73
- for content in rec (node ._children ["+" ], i + 1 ):
86
+ if '+' in node ._children and (normal or i > 0 ):
87
+ for content in rec (node ._children ['+' ], i + 1 ):
74
88
yield content
75
- if "#" in node ._children and (normal or i > 0 ):
76
- content = node ._children ["#" ]._content
89
+ if '#' in node ._children and (normal or i > 0 ):
90
+ content = node ._children ['#' ]._content
77
91
if content is not None :
78
92
yield content
79
-
80
- return rec (self ._root )
93
+ return rec (self ._root )
0 commit comments