Update Reference Sources to .NET Framework 4.6.1
[mono.git] / mcs / class / referencesource / System.ServiceModel / System / ServiceModel / Dispatcher / PrefixEndpointAddressMessageFilterTable.cs
1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //-----------------------------------------------------------------------------
4 namespace System.ServiceModel.Dispatcher
5 {
6     using System;
7     using System.Runtime;
8     using System.ServiceModel;
9     using System.ServiceModel.Channels;
10
11     class PrefixEndpointAddressMessageFilterTable<TFilterData> : EndpointAddressMessageFilterTable<TFilterData>
12     {
13         UriPrefixTable<CandidateSet> toHostTable;
14         UriPrefixTable<CandidateSet> toNoHostTable;
15
16         public PrefixEndpointAddressMessageFilterTable()
17             : base()
18         {
19         }
20
21         protected override void InitializeLookupTables()
22         {
23             this.toHostTable = new UriPrefixTable<CandidateSet>();
24             this.toNoHostTable = new UriPrefixTable<CandidateSet>();
25         }
26
27         public override void Add(MessageFilter filter, TFilterData data)
28         {
29             if (filter == null)
30             {
31                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter");
32             }
33
34             Add((PrefixEndpointAddressMessageFilter)filter, data);
35         }
36
37         public override void Add(EndpointAddressMessageFilter filter, TFilterData data)
38         {
39             if (filter == null)
40             {
41                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter");
42             }
43
44             Fx.Assert("EndpointAddressMessageFilter cannot be added to PrefixEndpointAddressMessageFilterTable");
45             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException("EndpointAddressMessageFilter cannot be added to PrefixEndpointAddressMessageFilterTable"));
46         }
47
48         public void Add(PrefixEndpointAddressMessageFilter filter, TFilterData data)
49         {
50             if (filter == null)
51             {
52                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter");
53             }
54
55             this.filters.Add(filter, data);
56
57             // Create the candidate
58             byte[] mask = BuildMask(filter.HeaderLookup);
59             Candidate can = new Candidate(filter, data, mask, filter.HeaderLookup);
60             this.candidates.Add(filter, can);
61
62 #pragma warning suppress 56506 // [....], PrefixEndpointAddressMessageFilter.Address can never be null
63             Uri soapToAddress = filter.Address.Uri;
64
65             CandidateSet cset;
66             if (!TryMatchCandidateSet(soapToAddress, filter.IncludeHostNameInComparison, out cset))
67             {
68                 cset = new CandidateSet();
69                 GetAddressTable(filter.IncludeHostNameInComparison).RegisterUri(soapToAddress, GetComparisonMode(filter.IncludeHostNameInComparison), cset);
70             }
71             cset.candidates.Add(can);
72
73             IncrementQNameCount(cset, filter.Address);
74         }
75
76         HostNameComparisonMode GetComparisonMode(bool includeHostNameInComparison)
77         {
78             return includeHostNameInComparison ? HostNameComparisonMode.Exact : HostNameComparisonMode.StrongWildcard;
79         }
80
81         UriPrefixTable<CandidateSet> GetAddressTable(bool includeHostNameInComparison)
82         {
83             return includeHostNameInComparison ? this.toHostTable : this.toNoHostTable;
84         }
85
86         internal override bool TryMatchCandidateSet(Uri to, bool includeHostNameInComparison, out CandidateSet cset)
87         {
88             return GetAddressTable(includeHostNameInComparison).TryLookupUri(to, GetComparisonMode(includeHostNameInComparison), out cset);
89         }
90
91         protected override void ClearLookupTables()
92         {
93             this.toHostTable = new UriPrefixTable<EndpointAddressMessageFilterTable<TFilterData>.CandidateSet>();
94             this.toNoHostTable = new UriPrefixTable<EndpointAddressMessageFilterTable<TFilterData>.CandidateSet>();
95         }
96
97         public override bool Remove(MessageFilter filter)
98         {
99             if (filter == null)
100             {
101                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter");
102             }
103
104             PrefixEndpointAddressMessageFilter pFilter = filter as PrefixEndpointAddressMessageFilter;
105             if (pFilter != null)
106             {
107                 return Remove(pFilter);
108             }
109
110             return false;
111         }
112
113         public override bool Remove(EndpointAddressMessageFilter filter)
114         {
115             if (filter == null)
116             {
117                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter");
118             }
119
120             Fx.Assert("EndpointAddressMessageFilter cannot be removed from PrefixEndpointAddressMessageFilterTable");
121             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException("EndpointAddressMessageFilter cannot be removed from PrefixEndpointAddressMessageFilterTable"));
122         }
123
124         public bool Remove(PrefixEndpointAddressMessageFilter filter)
125         {
126             if (filter == null)
127             {
128                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter");
129             }
130
131             if (!this.filters.Remove(filter))
132             {
133                 return false;
134             }
135
136             Candidate can = this.candidates[filter];
137 #pragma warning suppress 56506 // [....], PrefixEndpointAddressMessageFilter.Address can never be null
138             Uri soapToAddress = filter.Address.Uri;
139
140             CandidateSet cset = null;
141             if (TryMatchCandidateSet(soapToAddress, filter.IncludeHostNameInComparison, out cset))
142             {
143                 if (cset.candidates.Count == 1)
144                 {
145                     GetAddressTable(filter.IncludeHostNameInComparison).UnregisterUri(soapToAddress, GetComparisonMode(filter.IncludeHostNameInComparison));
146                 }
147                 else
148                 {
149                     DecrementQNameCount(cset, filter.Address);
150
151                     // Remove Candidate
152                     cset.candidates.Remove(can);
153                 }
154             }
155             this.candidates.Remove(filter);
156
157             RebuildMasks();
158             return true;
159         }
160     }
161 }