5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2006 Novell, Inc. http://www.novell.com
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
29 using System
.Runtime
.Serialization
;
33 namespace System
.ServiceModel
.Channels
35 internal class XmlReaderMessage
: Message
37 MessageVersion version
;
38 XmlDictionaryReader reader
;
39 MessageHeaders headers
;
40 MessageProperties properties
= new MessageProperties ();
41 bool is_empty
, is_fault
, body_started
, body_consumed
;
44 public XmlReaderMessage (MessageVersion version
, XmlDictionaryReader reader
, int maxSizeOfHeaders
)
46 this.version
= version
;
48 this.max_headers
= maxSizeOfHeaders
;
53 public override MessageHeaders Headers
{
61 public override bool IsEmpty
{
69 public override bool IsFault
{
77 public override MessageProperties Properties
{
78 get { return properties; }
81 public override MessageVersion Version
{
82 get { return version; }
85 protected override string OnGetBodyAttribute (
86 string localName
, string ns
)
90 return reader
.GetAttribute (localName
, ns
);
93 protected override XmlDictionaryReader
OnGetReaderAtBodyContents ()
95 if (reader
.ReadState
== ReadState
.Closed
)
96 return reader
; // silly, but that's what our test expects.
98 throw new InvalidOperationException ("The message body XmlReader is already consumed.");
102 throw new InvalidOperationException ("The message body is empty.");
103 body_consumed
= true;
107 protected override void OnWriteBodyContents (
108 XmlDictionaryWriter writer
)
110 XmlDictionaryReader reader
= GetReaderAtBodyContents ();
111 while (!reader
.EOF
&& reader
.NodeType
!= XmlNodeType
.EndElement
)
112 writer
.WriteNode (reader
, false);
115 static readonly char [] whitespaceChars
= new char [] {' ', '\t', '\r', '\n'}
;
117 void ReadEnvelopeStart ()
119 reader
.MoveToContent ();
120 if (reader
.IsEmptyElement
)
121 throw new ArgumentException ("Missing message content XML.");
122 reader
.ReadStartElement ("Envelope", Version
.Envelope
.Namespace
);
125 reader
.MoveToContent ();
131 throw new InvalidOperationException ("XmlReader at headers is already consumed.");
133 string envNS
= Version
.Envelope
.Namespace
;
135 headers
= new MessageHeaders (version
, max_headers
);
136 if (reader
.LocalName
!= "Header" || reader
.NamespaceURI
!= envNS
)
139 bool isEmptyHeader
= reader
.IsEmptyElement
;
140 reader
.ReadStartElement ("Header", envNS
);
141 reader
.MoveToContent ();
145 while (!reader
.EOF
&& reader
.NodeType
!= XmlNodeType
.EndElement
) {
146 if (reader
.NodeType
== XmlNodeType
.Element
)
147 headers
.Add (new MessageHeader
.RawMessageHeader (reader
, envNS
));
150 // FIXME: handle UnderstoodHeaders as well.
151 reader
.MoveToContent ();
153 reader
.ReadEndElement ();
154 reader
.MoveToContent ();
157 void ReadBodyStart ()
159 // read headers in advance.
165 is_empty
= reader
.IsEmptyElement
;
166 if (reader
.MoveToAttribute ("Id", Constants
.WsuNamespace
)) {
167 BodyId
= reader
.Value
;
168 reader
.MoveToElement ();
170 reader
.ReadStartElement ("Body", Version
.Envelope
.Namespace
);
171 if (reader
.NodeType
== XmlNodeType
.EndElement
) {
175 reader
.MoveToContent ();
176 if (reader
.NodeType
== XmlNodeType
.Element
&&
177 reader
.LocalName
== "Fault" &&
178 reader
.NamespaceURI
== Version
.Envelope
.Namespace
)
184 internal abstract class MessageImplBase
: Message
186 MessageHeaders headers
;
187 MessageProperties properties
= new MessageProperties ();
189 public MessageImplBase (MessageVersion version
, string action
)
191 headers
= new MessageHeaders (version
);
193 headers
.Action
= action
;
196 public override MessageHeaders Headers
{
197 get { return headers; }
200 public override MessageProperties Properties
{
201 get { return properties; }
204 public override MessageVersion Version
{
205 get { return Headers.MessageVersion; }
209 internal class EmptyMessage
: MessageImplBase
211 public EmptyMessage (MessageVersion version
, string action
)
212 : base (version
, action
)
216 public override bool IsEmpty
{
220 protected override void OnWriteBodyContents (
221 XmlDictionaryWriter writer
)
225 protected override MessageBuffer
OnCreateBufferedCopy (
228 return new DefaultMessageBuffer (Headers
, Properties
);
232 internal class SimpleMessage
: MessageImplBase
237 public SimpleMessage (MessageVersion version
,
238 string action
, BodyWriter body
, bool isFault
)
239 : base (version
, action
)
242 this.is_fault
= isFault
;
245 public override bool IsEmpty
{
246 get { return false; }
249 public override bool IsFault
{
250 get { return is_fault; }
253 protected override void OnWriteBodyContents (
254 XmlDictionaryWriter writer
)
256 body
.WriteBodyContents (writer
);
259 protected override MessageBuffer
OnCreateBufferedCopy (
262 var headers
= new MessageHeaders (Headers
);
263 var props
= new MessageProperties (Properties
);
264 return new DefaultMessageBuffer (maxBufferSize
, headers
, props
, body
.CreateBufferedCopy (maxBufferSize
), false);