Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.ServiceModel / System / ServiceModel / Dispatcher / ActionMessageFilterTable.cs
blob9f4d8c9c0bcf787fb433b76816736539bf9b72d6
1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //-----------------------------------------------------------------------------
4 namespace System.ServiceModel.Dispatcher
6 using System;
7 using System.ServiceModel.Channels;
8 using System.Collections;
9 using System.Collections.Generic;
10 using System.Collections.ObjectModel;
11 using System.ServiceModel.Diagnostics;
12 using System.Runtime.Serialization;
14 [DataContract]
15 internal class ActionMessageFilterTable<TFilterData> : IMessageFilterTable<TFilterData>
17 Dictionary<MessageFilter, TFilterData> filters;
18 Dictionary<string, List<MessageFilter>> actions;
19 List<MessageFilter> always;
21 public ActionMessageFilterTable()
23 Init();
26 void Init()
28 this.filters = new Dictionary<MessageFilter, TFilterData>();
29 this.actions = new Dictionary<string, List<MessageFilter>>();
30 this.always = new List<MessageFilter>();
33 public TFilterData this[MessageFilter filter]
35 get
37 return this.filters[filter];
39 set
41 if (this.filters.ContainsKey(filter))
43 this.filters[filter] = value;
45 else
47 this.Add(filter, value);
52 public int Count
54 get
56 return this.filters.Count;
60 [DataMember(IsRequired = true)]
61 Entry[] Entries
63 get
65 Entry[] entries = new Entry[Count];
66 int i = 0;
67 foreach (KeyValuePair<MessageFilter, TFilterData> item in filters)
68 entries[i++] = new Entry(item.Key, item.Value);
70 return entries;
72 set
74 Init();
76 for (int i = 0; i < value.Length; ++i)
77 Add(value[i].filter, value[i].data);
81 public bool IsReadOnly
83 get
85 return false;
89 public ICollection<MessageFilter> Keys
91 get
93 return this.filters.Keys;
97 public ICollection<TFilterData> Values
99 get
101 return this.filters.Values;
105 public void Add(ActionMessageFilter filter, TFilterData data)
107 if (filter == null)
109 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter");
112 this.filters.Add(filter, data);
113 List<MessageFilter> filters;
114 #pragma warning suppress 56506 // Microsoft, Actions will never be null
115 if (filter.Actions.Count == 0)
117 this.always.Add(filter);
119 else
121 for (int i = 0; i < filter.Actions.Count; ++i)
123 if (!this.actions.TryGetValue(filter.Actions[i], out filters))
125 filters = new List<MessageFilter>();
126 this.actions.Add(filter.Actions[i], filters);
128 filters.Add(filter);
133 public void Add(MessageFilter filter, TFilterData data)
135 if (filter == null)
137 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter");
140 Add((ActionMessageFilter)filter, data);
143 public void Add(KeyValuePair<MessageFilter, TFilterData> item)
145 Add(item.Key, item.Value);
148 public void Clear()
150 this.filters.Clear();
151 this.actions.Clear();
152 this.always.Clear();
155 public bool Contains(KeyValuePair<MessageFilter, TFilterData> item)
157 return ((ICollection<KeyValuePair<MessageFilter, TFilterData>>)this.filters).Contains(item);
160 public bool ContainsKey(MessageFilter filter)
162 return this.filters.ContainsKey(filter);
165 public void CopyTo(KeyValuePair<MessageFilter, TFilterData>[] array, int arrayIndex)
167 ((ICollection<KeyValuePair<MessageFilter, TFilterData>>)this.filters).CopyTo(array, arrayIndex);
170 IEnumerator IEnumerable.GetEnumerator()
172 return this.GetEnumerator();
175 public IEnumerator<KeyValuePair<MessageFilter, TFilterData>> GetEnumerator()
177 return ((ICollection<KeyValuePair<MessageFilter, TFilterData>>)this.filters).GetEnumerator();
180 MessageFilter InnerMatch(Message message)
182 string act = message.Headers.Action;
183 if (act == null)
185 act = string.Empty;
188 List<MessageFilter> filters;
189 if (this.actions.TryGetValue(act, out filters))
191 if (this.always.Count + filters.Count > 1)
193 List<MessageFilter> tmp = new List<MessageFilter>(filters);
194 tmp.AddRange(this.always);
195 Collection<MessageFilter> matches = new Collection<MessageFilter>(tmp);
196 throw TraceUtility.ThrowHelperError(new MultipleFilterMatchesException(SR.GetString(SR.FilterMultipleMatches), null, matches), message);
198 return filters[0];
201 if (this.always.Count > 1)
203 Collection<MessageFilter> matches = new Collection<MessageFilter>(new List<MessageFilter>(this.always));
204 throw TraceUtility.ThrowHelperError(new MultipleFilterMatchesException(SR.GetString(SR.FilterMultipleMatches), null, matches), message);
206 else if (this.always.Count == 1)
208 return this.always[0];
211 return null;
214 void InnerMatch(Message message, ICollection<MessageFilter> results)
216 for (int i = 0; i < this.always.Count; ++i)
218 results.Add(this.always[i]);
221 string act = message.Headers.Action;
222 if (act == null)
224 act = string.Empty;
227 List<MessageFilter> filters;
228 if (this.actions.TryGetValue(act, out filters))
230 for (int i = 0; i < filters.Count; ++i)
232 results.Add(filters[i]);
237 void InnerMatchData(Message message, ICollection<TFilterData> results)
239 for (int i = 0; i < this.always.Count; ++i)
241 results.Add(this.filters[this.always[i]]);
244 string act = message.Headers.Action;
245 if (act == null)
247 act = string.Empty;
250 List<MessageFilter> filters;
251 if (this.actions.TryGetValue(act, out filters))
253 for (int i = 0; i < filters.Count; ++i)
255 results.Add(this.filters[filters[i]]);
260 public bool GetMatchingValue(Message message, out TFilterData data)
262 if (message == null)
264 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
267 MessageFilter f = InnerMatch(message);
268 if (f == null)
270 data = default(TFilterData);
271 return false;
274 data = this.filters[f];
275 return true;
278 public bool GetMatchingValue(MessageBuffer messageBuffer, out TFilterData data)
280 if (messageBuffer == null)
282 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("messageBuffer");
285 MessageFilter f = null;
286 Message msg = messageBuffer.CreateMessage();
289 f = InnerMatch(msg);
291 finally
293 msg.Close();
296 if (f == null)
298 data = default(TFilterData);
299 return false;
302 data = this.filters[f];
303 return true;
306 public bool GetMatchingFilter(Message message, out MessageFilter filter)
308 if (message == null)
310 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
313 filter = InnerMatch(message);
314 return filter != null;
317 public bool GetMatchingFilter(MessageBuffer messageBuffer, out MessageFilter filter)
319 if (messageBuffer == null)
321 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("messageBuffer");
324 Message msg = messageBuffer.CreateMessage();
327 filter = InnerMatch(msg);
328 return filter != null;
330 finally
332 msg.Close();
336 public bool GetMatchingFilters(Message message, ICollection<MessageFilter> results)
338 if (message == null)
340 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
343 if (results == null)
345 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("results");
348 int count = results.Count;
349 InnerMatch(message, results);
350 return count != results.Count;
353 public bool GetMatchingFilters(MessageBuffer messageBuffer, ICollection<MessageFilter> results)
355 if (messageBuffer == null)
357 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("messageBuffer");
360 if (results == null)
362 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("results");
365 Message msg = messageBuffer.CreateMessage();
368 int count = results.Count;
369 InnerMatch(msg, results);
370 return count != results.Count;
372 finally
374 msg.Close();
378 public bool GetMatchingValues(Message message, ICollection<TFilterData> results)
380 if (message == null)
382 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
385 if (results == null)
387 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("results");
390 int count = results.Count;
391 InnerMatchData(message, results);
392 return count != results.Count;
395 public bool GetMatchingValues(MessageBuffer messageBuffer, ICollection<TFilterData> results)
397 if (messageBuffer == null)
399 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("messageBuffer");
402 if (results == null)
404 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("results");
407 Message msg = messageBuffer.CreateMessage();
410 int count = results.Count;
411 InnerMatchData(msg, results);
412 return count != results.Count;
414 finally
416 msg.Close();
420 public bool Remove(ActionMessageFilter filter)
422 if (filter == null)
424 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter");
427 if (this.filters.Remove(filter))
429 #pragma warning suppress 56506 // Microsoft, ActionMessageFilter.Actions can never be null
430 if (filter.Actions.Count == 0)
432 this.always.Remove(filter);
434 else
436 List<MessageFilter> filters;
437 for (int i = 0; i < filter.Actions.Count; ++i)
439 #pragma warning suppress 56506 // Microsoft, PreSharp generates a false error here
440 filters = this.actions[filter.Actions[i]];
441 #pragma warning suppress 56506 // Microsoft, filters can never be null
442 if (filters.Count == 1)
444 this.actions.Remove(filter.Actions[i]);
446 else
448 filters.Remove(filter);
452 return true;
454 return false;
457 public bool Remove(MessageFilter filter)
459 if (filter == null)
461 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter");
464 ActionMessageFilter aFilter = filter as ActionMessageFilter;
465 if (aFilter != null)
467 return Remove(aFilter);
469 return false;
472 public bool Remove(KeyValuePair<MessageFilter, TFilterData> item)
474 if (((ICollection<KeyValuePair<MessageFilter, TFilterData>>)this.filters).Contains(item))
476 return Remove(item.Key);
478 return false;
481 public bool TryGetValue(MessageFilter filter, out TFilterData data)
483 return this.filters.TryGetValue(filter, out data);
486 [DataContract]
487 class Entry
489 [DataMember(IsRequired = true)]
490 internal MessageFilter filter;
492 [DataMember(IsRequired = true)]
493 internal TFilterData data;
495 internal Entry(MessageFilter f, TFilterData d)
497 filter = f;
498 data = d;