Mono.Zeroconf – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 // Copyright 2007 Alp Toker <alp@atoker.com>
2 // This software is made available under the MIT License
3 // See COPYING for details
4  
5 using System;
6 using System.Text;
7 using System.Collections.Generic;
8  
9 namespace NDesk.DBus
10 {
11 //delegate void MessageHandler (Message msg);
12  
13 class MatchRule
14 {
15 public MessageType? MessageType;
16 public string Interface;
17 public string Member;
18 public ObjectPath Path;
19 public string Sender;
20 public string Destination;
21 public readonly SortedDictionary<int,string> Args = new SortedDictionary<int,string> ();
22  
23 public MatchRule ()
24 {
25 }
26  
27 void Append (StringBuilder sb, string key, string value)
28 {
29 if (sb.Length != 0)
30 sb.Append (",");
31  
32 sb.Append (key + "='");
33 sb.Append (value);
34 sb.Append ("'");
35 }
36  
37 void AppendArg (StringBuilder sb, int index, string value)
38 {
39 Append (sb, "arg" + index, value);
40 }
41  
42 public override bool Equals (object o)
43 {
44 MatchRule r = o as MatchRule;
45  
46 if (r == null)
47 return false;
48  
49 if (r.MessageType != MessageType)
50 return false;
51  
52 if (r.Interface != Interface)
53 return false;
54  
55 if (r.Member != Member)
56 return false;
57  
58 //TODO: see why path comparison doesn't work
59 if (r.Path.Value != Path.Value)
60 //if (r.Path != Path)
61 return false;
62  
63 if (r.Sender != Sender)
64 return false;
65  
66 if (r.Destination != Destination)
67 return false;
68  
69 //FIXME: do args
70  
71 return true;
72 }
73  
74 public override int GetHashCode ()
75 {
76 //FIXME: not at all optimal
77 return ToString ().GetHashCode ();
78 }
79  
80 public override string ToString ()
81 {
82 StringBuilder sb = new StringBuilder ();
83  
84 if (MessageType != null)
85 Append (sb, "type", MessageFilter.MessageTypeToString ((MessageType)MessageType));
86  
87 if (Interface != null)
88 Append (sb, "interface", Interface);
89  
90 if (Member != null)
91 Append (sb, "member", Member);
92  
93 if (Path != null)
94 //Append (sb, "path", Path.ToString ());
95 Append (sb, "path", Path.Value);
96  
97 if (Sender != null)
98 Append (sb, "sender", Sender);
99  
100 if (Destination != null)
101 Append (sb, "destination", Destination);
102  
103 if (Args != null) {
104 foreach (KeyValuePair<int,string> pair in Args)
105 AppendArg (sb, pair.Key, pair.Value);
106 }
107  
108 return sb.ToString ();
109 }
110  
111 //this is useful as a Predicate<Message> delegate
112 public bool Matches (Message msg)
113 {
114 if (MessageType != null)
115 if (msg.Header.MessageType != MessageType)
116 return false;
117  
118 object value;
119  
120 if (Interface != null)
121 if (msg.Header.Fields.TryGetValue (FieldCode.Interface, out value))
122 if ((string)value != Interface)
123 return false;
124  
125 if (Member != null)
126 if (msg.Header.Fields.TryGetValue (FieldCode.Member, out value))
127 if ((string)value != Member)
128 return false;
129  
130 if (Path != null)
131 if (msg.Header.Fields.TryGetValue (FieldCode.Path, out value))
132 //if ((ObjectPath)value != Path)
133 if (((ObjectPath)value).Value != Path.Value)
134 return false;
135  
136 if (Sender != null)
137 if (msg.Header.Fields.TryGetValue (FieldCode.Sender, out value))
138 if ((string)value != Sender)
139 return false;
140  
141 if (Destination != null)
142 if (msg.Header.Fields.TryGetValue (FieldCode.Destination, out value))
143 if ((string)value != Destination)
144 return false;
145  
146 //FIXME: do args
147  
148 return true;
149 }
150  
151 //this could be made more efficient
152 public static MatchRule Parse (string text)
153 {
154 MatchRule r = new MatchRule ();
155  
156 foreach (string propStr in text.Split (',')) {
157 string[] parts = propStr.Split ('=');
158  
159 if (parts.Length < 2)
160 throw new Exception ("No equals sign found");
161 if (parts.Length > 2)
162 throw new Exception ("Too many equals signs found");
163  
164 string key = parts[0].Trim ();
165 string value = parts[1].Trim ();
166  
167 if (!value.StartsWith ("'") || !value.EndsWith ("'"))
168 throw new Exception ("Too many equals signs found");
169  
170 value = value.Substring (1, value.Length - 2);
171  
172 if (key.StartsWith ("arg")) {
173 int argnum = Int32.Parse (key.Remove (0, "arg".Length));
174  
175 if (argnum < 0 || argnum > 63)
176 throw new Exception ("arg match must be between 0 and 63 inclusive");
177  
178 if (r.Args.ContainsKey (argnum))
179 return null;
180  
181 r.Args[argnum] = value;
182  
183 continue;
184 }
185  
186 //TODO: more consistent error handling
187 switch (key) {
188 case "type":
189 if (r.MessageType != null)
190 return null;
191 r.MessageType = MessageFilter.StringToMessageType (value);
192 break;
193 case "interface":
194 if (r.Interface != null)
195 return null;
196 r.Interface = value;
197 break;
198 case "member":
199 if (r.Member != null)
200 return null;
201 r.Member = value;
202 break;
203 case "path":
204 if (r.Path != null)
205 return null;
206 r.Path = new ObjectPath (value);
207 break;
208 case "sender":
209 if (r.Sender != null)
210 return null;
211 r.Sender = value;
212 break;
213 case "destination":
214 if (r.Destination != null)
215 return null;
216 r.Destination = value;
217 break;
218 default:
219 if (Protocol.Verbose)
220 Console.Error.WriteLine ("Warning: Unrecognized match rule key: " + key);
221 break;
222 }
223 }
224  
225 return r;
226 }
227 }
228 }