[LoongArch64] Part-5:add loongarch support in some files for LoongArch64. (#21769)
[mono-project.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / Message.cs
bloba5e5b39ec653c203ec48a20cf641dcd411f27fc4
1 //
2 // Message.cs
3 //
4 // Author:
5 // Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2005-2006,2010 Novell, Inc. http://www.novell.com
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 using System;
29 using System.Collections.Generic;
30 using System.IO;
31 using System.Runtime.Serialization;
32 using System.Xml;
33 using System.Xml.Schema;
35 namespace System.ServiceModel.Channels
37 public abstract class Message : IDisposable
39 bool disposed;
40 string body_id;
41 Message copied_message;
42 string string_cache;
44 protected Message () {
45 State = MessageState.Created;
48 public abstract MessageHeaders Headers { get; }
50 public virtual bool IsEmpty {
51 get { return false; }
54 public virtual bool IsFault {
55 get { return false; }
58 public abstract MessageProperties Properties { get; }
60 public MessageState State { get; private set; }
62 public abstract MessageVersion Version { get; }
64 protected bool IsDisposed {
65 get { return disposed; }
68 public void Close ()
70 if (!disposed)
71 OnClose ();
72 State = MessageState.Closed;
73 disposed = true;
76 public MessageBuffer CreateBufferedCopy (int maxBufferSize)
78 if (State != MessageState.Created)
79 throw new InvalidOperationException (String.Format ("The message is already at {0} state", State));
81 if (copied_message != null)
82 return copied_message.CreateBufferedCopy (maxBufferSize);
84 try {
85 return OnCreateBufferedCopy (maxBufferSize);
86 } finally {
87 State = MessageState.Copied;
91 void IDisposable.Dispose ()
93 Close ();
96 public T GetBody<T> ()
98 return OnGetBody<T> (GetReaderAtBodyContents ());
101 public T GetBody<T> (XmlObjectSerializer serializer)
103 // FIXME: Somehow use OnGetBody() here as well?
104 return (T)serializer.ReadObject (GetReaderAtBodyContents ());
107 protected virtual T OnGetBody<T> (XmlDictionaryReader reader)
109 var xmlFormatter = new DataContractSerializer (typeof (T));
110 return (T)xmlFormatter.ReadObject (reader);
113 public string GetBodyAttribute (string localName, string ns)
115 return OnGetBodyAttribute (localName, ns);
118 public XmlDictionaryReader GetReaderAtBodyContents ()
120 if (copied_message != null)
121 return copied_message.GetReaderAtBodyContents ();
123 return OnGetReaderAtBodyContents ();
126 public override string ToString ()
128 if (string_cache != null)
129 return string_cache;
131 StringWriter sw = new StringWriter ();
132 XmlWriterSettings settings = new XmlWriterSettings ();
133 settings.Indent = true;
134 settings.OmitXmlDeclaration = true;
136 using (XmlWriter w = XmlWriter.Create (sw, settings)) {
137 OnBodyToString (XmlDictionaryWriter.CreateDictionaryWriter (w));
139 string_cache = sw.ToString ();
140 return string_cache;
143 void WriteXsiNil (XmlDictionaryWriter writer)
145 var dic = Constants.SoapDictionary;
146 writer.WriteStartElement ("z", dic.Add ("anyType"), dic.Add (Constants.MSSerialization));
147 writer.WriteAttributeString ("i", dic.Add ("nil"), dic.Add ("http://www.w3.org/2001/XMLSchema-instance"), "true");
148 writer.WriteEndElement ();
151 public void WriteBody (XmlDictionaryWriter writer)
153 if (Version.Envelope != EnvelopeVersion.None)
154 WriteStartBody (writer);
155 WriteBodyContents (writer);
156 if (Version.Envelope != EnvelopeVersion.None)
157 writer.WriteEndElement ();
160 public void WriteBody (XmlWriter writer)
162 WriteBody (XmlDictionaryWriter.CreateDictionaryWriter (writer));
165 public void WriteBodyContents (XmlDictionaryWriter writer)
167 if (!IsEmpty) {
168 if (copied_message != null)
169 copied_message.WriteBodyContents (writer);
170 else
171 OnWriteBodyContents (writer);
173 else if (Version.Envelope == EnvelopeVersion.None)
174 WriteXsiNil (writer);
175 State = MessageState.Written;
178 public void WriteMessage (XmlDictionaryWriter writer)
180 if (State != MessageState.Created)
181 throw new InvalidOperationException (String.Format ("The message is already at {0} state", State));
183 OnWriteMessage (writer);
186 public void WriteMessage (XmlWriter writer)
188 WriteMessage (XmlDictionaryWriter.CreateDictionaryWriter (writer));
191 public void WriteStartBody (XmlDictionaryWriter writer)
193 if (State != MessageState.Created)
194 throw new InvalidOperationException (String.Format ("The message is already at {0} state", State));
196 OnWriteStartBody (writer);
199 public void WriteStartBody (XmlWriter writer)
201 WriteStartBody (
202 XmlDictionaryWriter.CreateDictionaryWriter (writer));
205 public void WriteStartEnvelope (XmlDictionaryWriter writer)
207 if (State != MessageState.Created)
208 throw new InvalidOperationException (String.Format ("The message is already at {0} state", State));
210 OnWriteStartEnvelope (writer);
213 protected virtual void OnBodyToString (
214 XmlDictionaryWriter writer)
216 MessageState tempState = State;
217 try {
218 var mb = CreateBufferedCopy (int.MaxValue);
219 copied_message = mb.CreateMessage ();
220 var msg = mb.CreateMessage ();
221 msg.WriteMessage (writer);
223 finally {
224 State = tempState;
228 protected virtual void OnClose ()
232 protected virtual MessageBuffer OnCreateBufferedCopy (
233 int maxBufferSize)
235 var s = new XmlWriterSettings ();
236 s.OmitXmlDeclaration = true;
237 s.ConformanceLevel = ConformanceLevel.Auto;
238 StringWriter sw = new StringWriter ();
239 using (XmlDictionaryWriter w = XmlDictionaryWriter.CreateDictionaryWriter (XmlWriter.Create (sw, s)))
240 WriteBodyContents (w);
241 var headers = new MessageHeaders (Headers);
242 var props = new MessageProperties (Properties);
243 return new DefaultMessageBuffer (maxBufferSize, headers, props, new XmlReaderBodyWriter (sw.ToString (), maxBufferSize, null), false, new AttributeCollection ());
246 protected virtual string OnGetBodyAttribute (
247 string localName, string ns)
249 return null;
252 protected virtual XmlDictionaryReader OnGetReaderAtBodyContents ()
254 var ws = new XmlWriterSettings ();
255 ws.ConformanceLevel = ConformanceLevel.Auto;
256 StringWriter sw = new StringWriter ();
257 using (XmlDictionaryWriter body = XmlDictionaryWriter.CreateDictionaryWriter (XmlWriter.Create (sw, ws))) {
258 WriteBodyContents (body);
261 var nt = new NameTable ();
262 var nsmgr = new XmlNamespaceManager (nt);
263 nsmgr.AddNamespace ("s", Version.Envelope.Namespace);
264 nsmgr.AddNamespace ("a", Version.Addressing.Namespace);
265 var pc = new XmlParserContext (nt, nsmgr, null, XmlSpace.None);
267 var rs = new XmlReaderSettings ();
268 rs.ConformanceLevel = ConformanceLevel.Auto;
270 return XmlDictionaryReader.CreateDictionaryReader (XmlReader.Create (new StringReader (sw.ToString ()), rs, pc));
273 protected abstract void OnWriteBodyContents (
274 XmlDictionaryWriter writer);
276 protected virtual void OnWriteMessage (
277 XmlDictionaryWriter writer)
279 if (Version.Envelope != EnvelopeVersion.None) {
280 WriteStartEnvelope (writer);
281 if (Headers.Count > 0) {
282 OnWriteStartHeaders (writer);
283 for (int i = 0, count = Headers.Count; i < count; i++)
284 Headers.WriteHeader (i, writer);
285 writer.WriteEndElement ();
288 WriteBody (writer);
289 if (Version.Envelope != EnvelopeVersion.None)
290 writer.WriteEndElement ();
293 protected virtual void OnWriteStartBody (
294 XmlDictionaryWriter writer)
296 var dic = Constants.SoapDictionary;
297 writer.WriteStartElement ("s", dic.Add ("Body"), dic.Add (Version.Envelope.Namespace));
300 protected virtual void OnWriteStartEnvelope (
301 XmlDictionaryWriter writer)
303 var dic = Constants.SoapDictionary;
304 writer.WriteStartElement ("s", dic.Add ("Envelope"), dic.Add (Version.Envelope.Namespace));
305 if (Headers.Action != null && Version.Addressing.Namespace != MessageVersion.None.Addressing.Namespace)
306 writer.WriteXmlnsAttribute ("a", dic.Add (Version.Addressing.Namespace));
307 foreach (MessageHeaderInfo h in Headers)
308 if (h.Id != null && writer.LookupPrefix (Constants.WsuNamespace) != "u") {
309 writer.WriteXmlnsAttribute ("u", dic.Add (Constants.WsuNamespace));
310 break;
314 protected virtual void OnWriteStartHeaders (
315 XmlDictionaryWriter writer)
317 var dic = Constants.SoapDictionary;
318 writer.WriteStartElement ("s", dic.Add ("Header"), dic.Add (Version.Envelope.Namespace));
321 #region factory methods
323 // 1) version, code, reason, action -> 3
324 // 2) version, code, reason, detail, action -> 3
325 // 3) version, fault, action -> SimpleMessage
326 // 4) version, action, body -> 10 or 5
327 // 5) version, action, body, formatter -> 10 or 9
328 // 6) version, action, xmlReader -> 7
329 // 7) version, action, reader -> 9
330 // 8) xmlReader, maxSizeOfHeaders, version -> 11
331 // 9) version, action, body -> SimpleMessage
332 // 10) version, action -> EmptyMessage
333 // 11) reader, maxSizeOfHeaders, version -> XmlReaderMessage
335 // 1)
336 public static Message CreateMessage (MessageVersion version,
337 FaultCode faultCode, string reason, string action)
339 MessageFault fault = MessageFault.CreateFault (faultCode, reason);
340 return CreateMessage (version, fault, action);
343 // 2)
344 public static Message CreateMessage (MessageVersion version,
345 FaultCode faultCode, string reason, object detail,
346 string action)
348 MessageFault fault = MessageFault.CreateFault (
349 faultCode, new FaultReason (reason), detail);
350 return CreateMessage (version, fault, action);
353 // 3)
354 public static Message CreateMessage (MessageVersion version,
355 MessageFault fault, string action)
357 return new SimpleMessage (version, action,
358 new MessageFaultBodyWriter (fault, version), true, empty_attributes);
361 // 4)
362 public static Message CreateMessage (MessageVersion version,
363 string action, object body)
365 return body == null ?
366 CreateMessage (version, action) :
367 CreateMessage (version, action, body, new DataContractSerializer (body.GetType ()));
370 // 5)
371 public static Message CreateMessage (MessageVersion version,
372 string action, object body, XmlObjectSerializer serializer)
374 return body == null ?
375 CreateMessage (version, action) :
376 CreateMessage (
377 version, action,
378 new XmlObjectSerializerBodyWriter (body, serializer));
381 // 6)
382 public static Message CreateMessage (MessageVersion version,
383 string action, XmlReader body)
385 return CreateMessage (version, action,
386 XmlDictionaryReader.CreateDictionaryReader (body));
389 // 7)
390 public static Message CreateMessage (MessageVersion version,
391 string action, XmlDictionaryReader body)
393 return CreateMessage (version, action,
394 new XmlReaderBodyWriter (body));
397 // 8)
398 public static Message CreateMessage (XmlReader envelopeReader,
399 int maxSizeOfHeaders, MessageVersion version)
401 return CreateMessage (
402 XmlDictionaryReader.CreateDictionaryReader (envelopeReader),
403 maxSizeOfHeaders,
404 version);
407 // Core implementations of CreateMessage.
409 static readonly AttributeCollection empty_attributes = new AttributeCollection ();
411 // 9)
412 public static Message CreateMessage (MessageVersion version,
413 string action, BodyWriter body)
415 if (version == null)
416 throw new ArgumentNullException ("version");
417 if (body == null)
418 throw new ArgumentNullException ("body");
419 return new SimpleMessage (version, action, body, false, empty_attributes);
422 // 10)
423 public static Message CreateMessage (MessageVersion version,
424 string action)
426 if (version == null)
427 throw new ArgumentNullException ("version");
428 return new EmptyMessage (version, action);
431 // 11)
432 public static Message CreateMessage (
433 XmlDictionaryReader envelopeReader,
434 int maxSizeOfHeaders,
435 MessageVersion version)
437 if (envelopeReader == null)
438 throw new ArgumentNullException ("envelopeReader");
439 if (version == null)
440 throw new ArgumentNullException ("version");
441 return new XmlReaderMessage (version,
442 envelopeReader, maxSizeOfHeaders);
445 #endregion