New tests.
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / XmlReaderBodyWriter.cs
index f7173c76294ecff2214bbe33518abca7657c100e..1cca9653e1cc8c0268df130ae58ac15293a0565c 100644 (file)
 //
 using System;
 using System.Collections.ObjectModel;
+using System.IO;
 using System.Runtime.Serialization;
 using System.Xml;
 
 namespace System.ServiceModel.Channels
 {
-       [MonoTODO ("Check if isBuffered works or not (I think it shouldn't).")]
        internal class XmlReaderBodyWriter : BodyWriter
        {
                XmlDictionaryReader reader;
+               string xml_bak;
+               XmlParserContext parser_context;
+               bool consumed;
+
+               public XmlReaderBodyWriter (string xml, int maxBufferSize, XmlParserContext ctx)
+                       : base (true)
+               {
+                       var settings = new XmlReaderSettings () {
+                               // FIXME: enable this line (once MaxCharactersInDocument is implemented)
+                               // MaxCharactersInDocument = maxBufferSize,
+                               ConformanceLevel = ConformanceLevel.Fragment
+                               };
+                       reader = XmlDictionaryReader.CreateDictionaryReader (XmlReader.Create (new StringReader (xml), settings, ctx));
+                       reader.MoveToContent ();
+                       xml_bak = xml;
+                       parser_context = ctx;
+               }
 
                public XmlReaderBodyWriter (XmlDictionaryReader reader)
                        : base (false)
@@ -44,17 +61,63 @@ namespace System.ServiceModel.Channels
                        this.reader = reader;
                }
 
-               [MonoTODO]
                protected override BodyWriter OnCreateBufferedCopy (
                        int maxBufferSize)
                {
-                       throw new NotSupportedException ();
+#if true
+                       if (xml_bak == null) {
+                               if (consumed)
+                                       throw new InvalidOperationException ("Body xml reader is already consumed");
+                               var sw = new StringWriter ();
+                               var xw = XmlDictionaryWriter.CreateDictionaryWriter (XmlWriter.Create (sw));
+                               xw.WriteStartElement (reader.Prefix, reader.LocalName, reader.NamespaceURI);
+                               xw.WriteAttributes (reader, false);
+
+                               var nsmgr = new XmlNamespaceManager (reader.NameTable);
+                               var inr = reader as IXmlNamespaceResolver;
+                               if (inr != null)
+                                       foreach (var p in inr.GetNamespacesInScope (XmlNamespaceScope.ExcludeXml))
+                                               if (xw.LookupPrefix (p.Value) != p.Key)
+                                                       xw.WriteXmlnsAttribute (p.Key, p.Value);
+                               if (!reader.IsEmptyElement) {
+                                       reader.Read ();
+                                       while (reader.NodeType != XmlNodeType.EndElement)
+                                               xw.WriteNode (reader, false);
+                               }
+                               xw.WriteEndElement ();
+
+                               xw.Close ();
+                               xml_bak = sw.ToString ();
+                               reader = null;
+                       }
+#else // FIXME: this should be better, but somehow doesn't work.
+                       if (xml_bak == null) {
+                               if (consumed)
+                                       throw new InvalidOperationException ("Body xml reader is already consumed");
+                               var nss = new XmlNamespaceManager (reader.NameTable);
+                               var nsr = reader as IXmlNamespaceResolver;
+                               if (nsr != null)
+                                       foreach (var p in nsr.GetNamespacesInScope (XmlNamespaceScope.ExcludeXml))
+                                               nss.AddNamespace (p.Key, p.Value);
+                               parser_context = new XmlParserContext (nss.NameTable, nss, reader.XmlLang, reader.XmlSpace);
+                               xml_bak = reader.ReadOuterXml ();
+                       }
+#endif
+                       return new XmlReaderBodyWriter (xml_bak, maxBufferSize, parser_context);
                }
 
                protected override void OnWriteBodyContents (
                        XmlDictionaryWriter writer)
                {
-                       writer.WriteNode (reader, false);
+                       if (consumed)
+                               throw new InvalidOperationException ("Body xml reader is already consumed");
+                       if (reader == null && String.IsNullOrEmpty (xml_bak))
+                               return;
+                       XmlReader r = xml_bak != null ? XmlReader.Create (new StringReader (xml_bak), null, parser_context) : reader;
+                       r.MoveToContent ();
+                       writer.WriteNode (r, false);
+                       if (xml_bak == null)
+                               consumed = true;
                }
        }
 }