[LoongArch64] Part-5:add loongarch support in some files for LoongArch64. (#21769)
[mono-project.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / MessageHeaders.cs
blob3ee4ef203dead9ccad1dac7978026a856031c5dd
1 //
2 // System.ServiceModel.MessageHeader.cs
3 //
4 // Author: Duncan Mak (duncan@novell.com)
5 //
6 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be
17 // included in all copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 using System;
29 using System.Collections;
30 using System.Collections.Generic;
31 using System.IO;
32 using System.Runtime.Serialization;
33 using System.ServiceModel;
34 using System.Xml;
36 namespace System.ServiceModel.Channels
38 public sealed class MessageHeaders : IEnumerable<MessageHeaderInfo>, IEnumerable
40 static readonly XmlReaderSettings reader_settings;
42 static MessageHeaders ()
44 reader_settings = new XmlReaderSettings ();
45 reader_settings.ConformanceLevel = ConformanceLevel.Fragment;
48 List<MessageHeaderInfo> l;
49 Dictionary<Type, XmlObjectSerializer> serializers =
50 new Dictionary<Type, XmlObjectSerializer> ();
51 MessageVersion version;
53 public MessageHeaders (MessageHeaders collection)
54 : this (collection.MessageVersion)
56 CopyHeadersFrom (collection);
59 public MessageHeaders (MessageVersion version)
60 : this (version, 10) // let's say 10 is the initial size
64 public MessageHeaders (MessageVersion version, int initialSize)
66 this.version = version;
67 l = new List<MessageHeaderInfo> (initialSize);
70 public void Add (MessageHeader header)
72 l.Add (header);
75 public void CopyHeaderFrom (Message message, int headerIndex)
77 CopyHeaderFrom (message.Headers, headerIndex);
80 public void Clear ()
82 l.Clear ();
85 public void CopyHeaderFrom (MessageHeaders collection, int headerIndex)
87 l.Add (collection [headerIndex]);
90 public void CopyHeadersFrom (Message message)
92 CopyHeadersFrom (message.Headers);
95 public void CopyHeadersFrom (MessageHeaders collection)
97 foreach (MessageHeaderInfo h in collection)
98 l.Add (h);
101 public void CopyTo (MessageHeaderInfo [] array, int index)
103 l.CopyTo (array, index);
106 public int FindHeader (string name, string ns)
108 return FindHeader (name, ns, null);
111 bool HasActor (string actor, string [] candidates)
113 foreach (string c in candidates)
114 if (c == actor)
115 return true;
116 return false;
119 public int FindHeader (string name, string ns, params string [] actors)
121 int found = 0;
122 int retval = -1;
124 for (int i = 0; i < l.Count; i++) {
125 MessageHeaderInfo info = l [i];
127 if (info.Name == name && info.Namespace == ns) {
128 if (found > 0)
129 throw new MessageHeaderException ("Found multiple matching headers.");
130 // When no actors are passed, it never
131 // matches such header that has an
132 // Actor.
133 if (actors == null && info.Actor == String.Empty ||
134 actors != null && HasActor (info.Actor, actors)) {
135 retval = i;
136 found++;
141 return retval;
144 public IEnumerator<MessageHeaderInfo> GetEnumerator ()
146 return l.GetEnumerator ();
149 XmlObjectSerializer GetSerializer<T> (int headerIndex)
151 if (!serializers.ContainsKey (typeof (T)))
152 serializers [typeof (T)] = new DataContractSerializer (typeof (T), this [headerIndex].Name, this [headerIndex].Namespace);
153 return serializers [typeof (T)];
156 public T GetHeader<T> (int index)
158 if (l.Count <= index)
159 throw new ArgumentOutOfRangeException ("index");
160 var dmh = l [index] as MessageHeader.DefaultMessageHeader;
161 if (dmh != null && dmh.Value != null && typeof (T).IsAssignableFrom (dmh.Value.GetType ()))
162 return (T) dmh.Value;
163 if (typeof (T) == typeof (EndpointAddress)) {
164 XmlDictionaryReader r = GetReaderAtHeader (index);
165 return r.NodeType != XmlNodeType.Element ? default (T) : (T) (object) EndpointAddress.ReadFrom (r);
167 else
168 return GetHeader<T> (index, GetSerializer<T> (index));
171 public T GetHeader<T> (int index, XmlObjectSerializer serializer)
173 if (serializer == null)
174 throw new ArgumentNullException ("serializer");
175 XmlDictionaryReader r = GetReaderAtHeader (index);
176 return (T) serializer.ReadObject (r, false);
179 public T GetHeader<T> (string name, string ns)
181 return GetHeader<T> (name, ns, (string []) null);
184 public T GetHeader<T> (string name, string ns, params string [] actors)
186 int idx = FindHeader (name, ns, actors);
188 if (idx == -1)
189 throw new MessageHeaderException (String.Format ("Header '{0}:{1}' was not found for the argument actors: {2}", ns, name, actors == null ? "(null)" : String.Join (",", actors)));
191 return GetHeader<T> (idx);
194 public T GetHeader<T> (string name, string ns, XmlObjectSerializer serializer)
196 if (serializer == null)
197 throw new ArgumentNullException ("serializer");
198 int idx = FindHeader (name, ns);
200 if (idx < 0)
201 throw new MessageHeaderException (String.Format ("Header '{0}:{1}' was not found", ns, name));
203 return GetHeader<T> (idx, serializer);
206 public XmlDictionaryReader GetReaderAtHeader (int headerIndex)
208 if (headerIndex >= l.Count)
209 throw new ArgumentOutOfRangeException (String.Format ("Index is out of range. Current header count is {0}", l.Count));
210 MessageHeader item = (MessageHeader) l [headerIndex];
212 XmlReader reader =
213 item is MessageHeader.XmlMessageHeader ?
214 ((MessageHeader.XmlMessageHeader) item).CreateReader () :
215 XmlReader.Create (
216 new StringReader (item.ToString ()),
217 reader_settings);
218 reader.MoveToContent ();
219 XmlDictionaryReader dr = XmlDictionaryReader.CreateDictionaryReader (reader);
220 dr.MoveToContent ();
221 return dr;
224 public bool HaveMandatoryHeadersBeenUnderstood ()
226 throw new NotImplementedException ();
229 public bool HaveMandatoryHeadersBeenUnderstood (params string [] actors)
231 throw new NotImplementedException ();
234 public void Insert (int headerIndex, MessageHeader header)
236 l.Insert (headerIndex, header);
239 public void RemoveAll (string name, string ns)
241 // Shuffle all the ones we want to keep to the start of the list
242 int j = 0;
243 for (int i = 0; i < l.Count; i++) {
244 if (l[i].Name != name || l[i].Namespace != ns) {
245 l [j++] = l[i];
248 // Trim the extra elements off the end of the list.
249 int count = l.Count - j;
250 for (int i = 0; i < count; i++)
251 l.RemoveAt (l.Count - 1);
254 public void RemoveAt (int headerIndex)
256 l.RemoveAt (headerIndex);
259 IEnumerator IEnumerable.GetEnumerator ()
261 return ((IEnumerable) l).GetEnumerator ();
264 public void WriteHeader (int headerIndex, XmlDictionaryWriter writer)
266 if (version.Envelope == EnvelopeVersion.None)
267 return;
268 WriteStartHeader (headerIndex, writer);
269 WriteHeaderContents (headerIndex, writer);
270 writer.WriteEndElement ();
273 public void WriteHeader (int headerIndex, XmlWriter writer)
275 WriteHeader (headerIndex, XmlDictionaryWriter.CreateDictionaryWriter (writer));
278 public void WriteHeaderContents (int headerIndex, XmlDictionaryWriter writer)
280 if (headerIndex > l.Count)
281 throw new ArgumentOutOfRangeException ("There is no header at position " + headerIndex + ".");
283 MessageHeader h = l [headerIndex] as MessageHeader;
285 h.WriteHeaderContents (writer, version);
288 public void WriteHeaderContents (int headerIndex, XmlWriter writer)
290 WriteHeaderContents (headerIndex, XmlDictionaryWriter.CreateDictionaryWriter (writer));
293 public void WriteStartHeader (int headerIndex, XmlDictionaryWriter writer)
295 if (headerIndex > l.Count)
296 throw new ArgumentOutOfRangeException ("There is no header at position " + headerIndex + ".");
298 MessageHeader h = l [headerIndex] as MessageHeader;
300 h.WriteStartHeader (writer, version);
303 public void WriteStartHeader (int headerIndex, XmlWriter writer)
305 WriteStartHeader (headerIndex, XmlDictionaryWriter.CreateDictionaryWriter (writer));
308 public string Action {
309 get {
310 int idx = FindHeader ("Action", version.Addressing.Namespace);
311 return idx < 0 ? null : GetHeader<string> (idx);
313 set {
314 RemoveAll ("Action", version.Addressing.Namespace);
315 if (value != null)
316 Add (MessageHeader.CreateHeader ("Action", version.Addressing.Namespace, value, true));
320 public int Count {
321 get { return l.Count; }
324 void AddEndpointAddressHeader (string name, string ns, EndpointAddress address)
326 if (address == null)
327 return;
328 if (MessageVersion.Addressing.Equals (AddressingVersion.WSAddressing10))
329 Add (MessageHeader.CreateHeader (name, ns, EndpointAddress10.FromEndpointAddress (address)));
330 #if !MOBILE
331 else if (MessageVersion.Addressing.Equals (AddressingVersion.WSAddressingAugust2004))
332 Add (MessageHeader.CreateHeader (name, ns, EndpointAddressAugust2004.FromEndpointAddress (address)));
333 #endif
334 else
335 throw new InvalidOperationException ("WS-Addressing header is not allowed for AddressingVersion.None");
338 public EndpointAddress FaultTo {
339 get {
340 int idx = FindHeader ("FaultTo", version.Addressing.Namespace);
341 return idx < 0 ? null : GetHeader<EndpointAddress> (idx);
343 set {
344 RemoveAll ("FaultTo", version.Addressing.Namespace);
345 if (value != null)
346 AddEndpointAddressHeader ("FaultTo", version.Addressing.Namespace, value);
350 public EndpointAddress From {
351 get {
352 int idx = FindHeader ("From", version.Addressing.Namespace);
353 return idx < 0 ? null : GetHeader<EndpointAddress> (idx);
355 set {
356 RemoveAll ("From", version.Addressing.Namespace);
357 if (value != null)
358 AddEndpointAddressHeader ("From", version.Addressing.Namespace, value);
362 public MessageHeaderInfo this [int index] {
363 get { return l [index]; }
366 public UniqueId MessageId {
367 get {
368 int idx = FindHeader ("MessageID", version.Addressing.Namespace);
369 return idx < 0 ? null : new UniqueId (GetHeader<string> (idx));
371 set {
372 if (version.Addressing == AddressingVersion.None && value != null)
373 throw new InvalidOperationException ("WS-Addressing header is not allowed for AddressingVersion.None");
375 RemoveAll ("MessageID", version.Addressing.Namespace);
376 if (value != null)
377 Add (MessageHeader.CreateHeader ("MessageID", version.Addressing.Namespace, value));
381 public MessageVersion MessageVersion { get { return version; } }
383 public UniqueId RelatesTo {
384 get {
385 int idx = FindHeader ("RelatesTo", version.Addressing.Namespace);
386 return idx < 0 ? null : new UniqueId (GetHeader<string> (idx));
388 set {
389 if (version.Addressing == AddressingVersion.None && value != null)
390 throw new InvalidOperationException ("WS-Addressing header is not allowed for AddressingVersion.None");
392 RemoveAll ("MessageID", version.Addressing.Namespace);
393 if (value != null)
394 Add (MessageHeader.CreateHeader ("RelatesTo", version.Addressing.Namespace, value));
399 public EndpointAddress ReplyTo {
400 get {
401 int idx = FindHeader ("ReplyTo", version.Addressing.Namespace);
402 return idx < 0 ? null : GetHeader<EndpointAddress> (idx);
404 set {
405 RemoveAll ("ReplyTo", version.Addressing.Namespace);
406 if (value != null)
407 AddEndpointAddressHeader ("ReplyTo", version.Addressing.Namespace, value);
411 public Uri To {
412 get {
413 int idx = FindHeader ("To", version.Addressing.Namespace);
414 //FIXME: return idx < 0 ? null : GetHeader<Uri> (idx);
415 return idx < 0 ? null : new Uri (GetHeader<string> (idx));
417 set {
418 RemoveAll ("To", version.Addressing.Namespace);
419 if (value != null)
420 Add (MessageHeader.CreateHeader ("To", version.Addressing.Namespace, value.AbsoluteUri, true));
424 [MonoTODO]
425 public UnderstoodHeaders UnderstoodHeaders {
426 get { throw new NotImplementedException (); }
429 public void SetAction (XmlDictionaryString action)
431 if (action == null)
432 Action = null;
433 else
434 Action = action.Value;