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
{
68 public override bool IsFault
{
75 public override MessageProperties Properties
{
76 get { return properties; }
79 public override MessageVersion Version
{
80 get { return version; }
83 protected override MessageBuffer
OnCreateBufferedCopy (
87 var headers
= new MessageHeaders (Headers
);
88 var props
= new MessageProperties (Properties
);
89 return new DefaultMessageBuffer (maxBufferSize
, headers
, props
, new XmlReaderBodyWriter (reader
), IsFault
);
92 protected override string OnGetBodyAttribute (
93 string localName
, string ns
)
97 return reader
.GetAttribute (localName
, ns
);
100 protected override XmlDictionaryReader
OnGetReaderAtBodyContents ()
102 if (reader
.ReadState
== ReadState
.Closed
)
103 return reader
; // silly, but that's what our test expects.
105 throw new InvalidOperationException ("The message body XmlReader is already consumed.");
108 throw new InvalidOperationException ("The message body is empty.");
109 body_consumed
= true;
113 protected override void OnWriteBodyContents (
114 XmlDictionaryWriter writer
)
116 XmlDictionaryReader reader
= GetReaderAtBodyContents ();
117 while (!reader
.EOF
&& reader
.NodeType
!= XmlNodeType
.EndElement
)
118 writer
.WriteNode (reader
, false);
121 static readonly char [] whitespaceChars
= new char [] {' ', '\t', '\r', '\n'}
;
123 void ReadEnvelopeStart ()
125 reader
.MoveToContent ();
126 if (reader
.IsEmptyElement
)
127 throw new ArgumentException ("Missing message content XML.");
128 reader
.ReadStartElement ("Envelope", Version
.Envelope
.Namespace
);
131 reader
.MoveToContent ();
137 throw new InvalidOperationException ("XmlReader at headers is already consumed.");
139 string envNS
= Version
.Envelope
.Namespace
;
141 headers
= new MessageHeaders (version
, max_headers
);
142 if (reader
.LocalName
!= "Header" || reader
.NamespaceURI
!= envNS
)
145 bool isEmptyHeader
= reader
.IsEmptyElement
;
146 reader
.ReadStartElement ("Header", envNS
);
147 reader
.MoveToContent ();
151 while (!reader
.EOF
&& reader
.NodeType
!= XmlNodeType
.EndElement
) {
152 if (reader
.NodeType
== XmlNodeType
.Element
)
153 headers
.Add (new MessageHeader
.RawMessageHeader (reader
, envNS
));
156 // FIXME: handle UnderstoodHeaders as well.
157 reader
.MoveToContent ();
159 reader
.ReadEndElement ();
160 reader
.MoveToContent ();
163 void ReadBodyStart ()
168 // read headers in advance.
174 is_empty
= reader
.IsEmptyElement
;
175 if (reader
.MoveToAttribute ("Id", Constants
.WsuNamespace
)) {
176 BodyId
= reader
.Value
;
177 reader
.MoveToElement ();
179 reader
.ReadStartElement ("Body", Version
.Envelope
.Namespace
);
180 if (reader
.NodeType
== XmlNodeType
.EndElement
) {
184 reader
.MoveToContent ();
185 if (reader
.NodeType
== XmlNodeType
.Element
&&
186 reader
.LocalName
== "Fault" &&
187 reader
.NamespaceURI
== Version
.Envelope
.Namespace
)
193 internal abstract class MessageImplBase
: Message
195 MessageHeaders headers
;
196 MessageProperties properties
= new MessageProperties ();
198 public MessageImplBase (MessageVersion version
, string action
)
200 headers
= new MessageHeaders (version
);
202 headers
.Action
= action
;
205 public override MessageHeaders Headers
{
206 get { return headers; }
209 public override MessageProperties Properties
{
210 get { return properties; }
213 public override MessageVersion Version
{
214 get { return Headers.MessageVersion; }
218 internal class EmptyMessage
: MessageImplBase
220 public EmptyMessage (MessageVersion version
, string action
)
221 : base (version
, action
)
225 public override bool IsEmpty
{
229 protected override void OnWriteBodyContents (
230 XmlDictionaryWriter writer
)
234 protected override MessageBuffer
OnCreateBufferedCopy (
237 return new DefaultMessageBuffer (Headers
, Properties
);
241 internal class SimpleMessage
: MessageImplBase
246 public SimpleMessage (MessageVersion version
,
247 string action
, BodyWriter body
, bool isFault
)
248 : base (version
, action
)
251 this.is_fault
= isFault
;
254 public override bool IsEmpty
{
255 get { return false; }
258 public override bool IsFault
{
259 get { return is_fault; }
262 protected override void OnWriteBodyContents (
263 XmlDictionaryWriter writer
)
265 body
.WriteBodyContents (writer
);
268 protected override MessageBuffer
OnCreateBufferedCopy (
271 var headers
= new MessageHeaders (Headers
);
272 var props
= new MessageProperties (Properties
);
273 return new DefaultMessageBuffer (maxBufferSize
, headers
, props
, body
.CreateBufferedCopy (maxBufferSize
), IsFault
);