2 // XmlReaderBodyWriter.cs
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
.Collections
.ObjectModel
;
31 using System
.Runtime
.Serialization
;
34 namespace System
.ServiceModel
.Channels
36 internal class XmlReaderBodyWriter
: BodyWriter
38 XmlDictionaryReader reader
;
40 XmlParserContext parser_context
;
43 public XmlReaderBodyWriter (string xml
, int maxBufferSize
, XmlParserContext ctx
)
46 var settings
= new XmlReaderSettings () {
47 // FIXME: enable this line (once MaxCharactersInDocument is implemented)
48 // MaxCharactersInDocument = maxBufferSize,
49 ConformanceLevel
= ConformanceLevel
.Fragment
51 reader
= XmlDictionaryReader
.CreateDictionaryReader (XmlReader
.Create (new StringReader (xml
), settings
, ctx
));
52 reader
.MoveToContent ();
57 public XmlReaderBodyWriter (XmlDictionaryReader reader
)
60 reader
.MoveToContent ();
64 protected override BodyWriter
OnCreateBufferedCopy (
68 if (xml_bak
== null) {
70 throw new InvalidOperationException ("Body xml reader is already consumed");
71 var sw
= new StringWriter ();
72 var xw
= XmlDictionaryWriter
.CreateDictionaryWriter (XmlWriter
.Create (sw
));
73 xw
.WriteStartElement (reader
.Prefix
, reader
.LocalName
, reader
.NamespaceURI
);
74 xw
.WriteAttributes (reader
, false);
76 var nsmgr
= new XmlNamespaceManager (reader
.NameTable
);
77 var inr
= reader
as IXmlNamespaceResolver
;
79 foreach (var p
in inr
.GetNamespacesInScope (XmlNamespaceScope
.ExcludeXml
))
80 if (xw
.LookupPrefix (p
.Value
) != p
.Key
)
81 xw
.WriteXmlnsAttribute (p
.Key
, p
.Value
);
82 if (!reader
.IsEmptyElement
) {
84 while (reader
.NodeType
!= XmlNodeType
.EndElement
)
85 xw
.WriteNode (reader
, false);
87 xw
.WriteEndElement ();
90 xml_bak
= sw
.ToString ();
93 #else // FIXME: this should be better, but somehow doesn't work.
94 if (xml_bak
== null) {
96 throw new InvalidOperationException ("Body xml reader is already consumed");
97 var nss
= new XmlNamespaceManager (reader
.NameTable
);
98 var nsr
= reader
as IXmlNamespaceResolver
;
100 foreach (var p
in nsr
.GetNamespacesInScope (XmlNamespaceScope
.ExcludeXml
))
101 nss
.AddNamespace (p
.Key
, p
.Value
);
102 parser_context
= new XmlParserContext (nss
.NameTable
, nss
, reader
.XmlLang
, reader
.XmlSpace
);
103 xml_bak
= reader
.ReadOuterXml ();
106 return new XmlReaderBodyWriter (xml_bak
, maxBufferSize
, parser_context
);
109 protected override void OnWriteBodyContents (
110 XmlDictionaryWriter writer
)
113 throw new InvalidOperationException ("Body xml reader is already consumed");
114 if (reader
== null && String
.IsNullOrEmpty (xml_bak
))
116 XmlReader r
= xml_bak
!= null ? XmlReader
.Create (new StringReader (xml_bak
), null, parser_context
) : reader
;
118 writer
.WriteNode (r
, false);