Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.ServiceModel / System / ServiceModel / Channels / AddressHeaderCollection.cs
1 //----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //----------------------------------------------------------------------------
4 namespace System.ServiceModel.Channels
5 {
6     using System.Collections.Generic;
7     using System.ServiceModel;
8     using System.Collections.ObjectModel;
9     using System.Diagnostics;
10     using System.Runtime.Serialization;
11     using System.Text;
12     using System.Xml;
13     using System.Xml.Schema;
14     using System.Xml.Serialization;
15     using System.ServiceModel.Security;
16     using System.IdentityModel.Claims;
17     using System.IdentityModel.Policy;
18
19     public sealed class AddressHeaderCollection : ReadOnlyCollection<AddressHeader>
20     {
21         static AddressHeaderCollection emptyHeaderCollection = new AddressHeaderCollection();
22
23         public AddressHeaderCollection()
24             : base(new List<AddressHeader>())
25         {
26         }
27
28         public AddressHeaderCollection(IEnumerable<AddressHeader> addressHeaders)
29             : base(new List<AddressHeader>(addressHeaders))
30         {
31             // avoid allocating an enumerator when possible
32             IList<AddressHeader> collection = addressHeaders as IList<AddressHeader>;
33             if (collection != null)
34             {
35                 for (int i = 0; i < collection.Count; i++)
36                 {
37                     if (collection[i] == null)
38                         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MessageHeaderIsNull0)));
39                 }
40             }
41             else
42             {
43                 foreach (AddressHeader addressHeader in addressHeaders)
44                 {
45                     if (addressHeaders == null)
46                         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MessageHeaderIsNull0)));
47                 }
48             }
49         }
50
51         internal static AddressHeaderCollection EmptyHeaderCollection
52         {
53             get { return emptyHeaderCollection; }
54         }
55
56         int InternalCount
57         {
58             get
59             {
60                 if (this == (object)emptyHeaderCollection)
61                     return 0;
62                 return Count;
63             }
64         }
65
66         public void AddHeadersTo(Message message)
67         {
68             if (message == null)
69                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
70
71             for (int i = 0; i < InternalCount; i++)
72             {
73 #pragma warning suppress 56506 // Microsoft, Message.Headers can never be null
74                 message.Headers.Add(this[i].ToMessageHeader());
75             }
76         }
77
78         public AddressHeader[] FindAll(string name, string ns)
79         {
80             if (name == null)
81                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("name"));
82             if (ns == null)
83                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("ns"));
84
85             List<AddressHeader> results = new List<AddressHeader>();
86             for (int i = 0; i < Count; i++)
87             {
88                 AddressHeader header = this[i];
89                 if (header.Name == name && header.Namespace == ns)
90                 {
91                     results.Add(header);
92                 }
93             }
94
95             return results.ToArray();
96         }
97
98         public AddressHeader FindHeader(string name, string ns)
99         {
100             if (name == null)
101                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("name"));
102             if (ns == null)
103                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("ns"));
104
105             AddressHeader matchingHeader = null;
106
107             for (int i = 0; i < Count; i++)
108             {
109                 AddressHeader header = this[i];
110                 if (header.Name == name && header.Namespace == ns)
111                 {
112                     if (matchingHeader != null)
113                         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MultipleMessageHeaders, name, ns)));
114                     matchingHeader = header;
115                 }
116             }
117
118             return matchingHeader;
119         }
120
121         internal bool IsEquivalent(AddressHeaderCollection col)
122         {
123             if (InternalCount != col.InternalCount)
124                 return false;
125
126             StringBuilder builder = new StringBuilder();
127             Dictionary<string, int> myHeaders = new Dictionary<string, int>();
128             PopulateHeaderDictionary(builder, myHeaders);
129
130             Dictionary<string, int> otherHeaders = new Dictionary<string, int>();
131             col.PopulateHeaderDictionary(builder, otherHeaders);
132
133             if (myHeaders.Count != otherHeaders.Count)
134                 return false;
135
136             foreach (KeyValuePair<string, int> pair in myHeaders)
137             {
138                 int count;
139                 if (otherHeaders.TryGetValue(pair.Key, out count))
140                 {
141                     if (count != pair.Value)
142                         return false;
143                 }
144                 else
145                 {
146                     return false;
147                 }
148             }
149
150             return true;
151         }
152
153         internal void PopulateHeaderDictionary(StringBuilder builder, Dictionary<string, int> headers)
154         {
155             string key;
156             for (int i = 0; i < InternalCount; ++i)
157             {
158                 builder.Remove(0, builder.Length);
159                 key = this[i].GetComparableForm(builder);
160                 if (headers.ContainsKey(key))
161                 {
162                     headers[key] = headers[key] + 1;
163                 }
164                 else
165                 {
166                     headers.Add(key, 1);
167                 }
168             }
169         }
170
171         internal static AddressHeaderCollection ReadServiceParameters(XmlDictionaryReader reader)
172         {
173             return ReadServiceParameters(reader, false);
174         }
175
176         internal static AddressHeaderCollection ReadServiceParameters(XmlDictionaryReader reader, bool isReferenceProperty)
177         {
178             reader.MoveToContent();
179             if (reader.IsEmptyElement)
180             {
181                 reader.Skip();
182                 return null;
183             }
184             else
185             {
186                 reader.ReadStartElement();
187                 List<AddressHeader> headerList = new List<AddressHeader>();
188                 while (reader.IsStartElement())
189                 {
190                     headerList.Add(new BufferedAddressHeader(reader, isReferenceProperty));
191                 }
192                 reader.ReadEndElement();
193                 return new AddressHeaderCollection(headerList);
194             }
195         }
196
197         internal bool HasReferenceProperties
198         {
199             get
200             {
201                 for (int i = 0; i < InternalCount; i++)
202                     if (this[i].IsReferenceProperty)
203                         return true;
204                 return false;
205             }
206         }
207
208         internal bool HasNonReferenceProperties
209         {
210             get
211             {
212                 for (int i = 0; i < InternalCount; i++)
213                     if (!this[i].IsReferenceProperty)
214                         return true;
215                 return false;
216             }
217         }
218
219         internal void WriteReferencePropertyContentsTo(XmlDictionaryWriter writer)
220         {
221             for (int i = 0; i < InternalCount; i++)
222                 if (this[i].IsReferenceProperty)
223                     this[i].WriteAddressHeader(writer);
224         }
225
226         internal void WriteNonReferencePropertyContentsTo(XmlDictionaryWriter writer)
227         {
228             for (int i = 0; i < InternalCount; i++)
229                 if (!this[i].IsReferenceProperty)
230                     this[i].WriteAddressHeader(writer);
231         }
232
233         internal void WriteContentsTo(XmlDictionaryWriter writer)
234         {
235             for (int i = 0; i < InternalCount; i++)
236                 this[i].WriteAddressHeader(writer);
237         }
238     }
239 }