79ab7b22beedf9ca50b33bc5ebf0bff32b42f4dd
[mono.git] / mcs / class / System.XML / System.Xml / XmlWriter.cs
1 //
2 // System.Xml.XmlWriter
3 //
4 // Authors:
5 //   Kral Ferch <kral_ferch@hotmail.com>
6 //   Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
7 //
8 // (C) 2002 Kral Ferch
9 // (C) 2002-2003 Atsushi Enomoto
10 // (C) 2004-2007 Novell, Inc.
11 //
12
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System;
35 using System.Collections;
36 using System.IO;
37 using System.Text;
38 using System.Xml.XPath;
39 #if NET_4_5
40 using System.Threading;
41 using System.Threading.Tasks;
42 #endif
43
44 namespace System.Xml
45 {
46         public abstract class XmlWriter : IDisposable
47         {
48                 XmlWriterSettings settings;
49
50                 #region Constructors
51
52                 protected XmlWriter () { }
53
54                 #endregion
55
56                 #region Properties
57
58                 public virtual XmlWriterSettings Settings {
59                         get { return settings; }
60                 }
61
62                 public abstract WriteState WriteState { get; }
63
64                 public virtual string XmlLang {
65                         get { return null; }
66                 }
67
68                 public virtual XmlSpace XmlSpace {
69                         get { return XmlSpace.None; }
70                 }
71
72                 #endregion
73
74                 #region Methods
75
76 #if NET_4_5
77                 public virtual void Close ()
78                 {
79                         if (asyncRunning)
80                                 throw new InvalidOperationException ("An asynchronous operation is already in progress.");
81                 }
82 #else
83                 public abstract void Close ();
84 #endif
85
86                 public static XmlWriter Create (Stream output)
87                 {
88                         return Create (output, null);
89                 }
90
91                 public static XmlWriter Create (string outputFileName)
92                 {
93                         return Create (outputFileName, null);
94                 }
95
96                 public static XmlWriter Create (TextWriter output)
97                 {
98                         return Create (output, null);
99                 }
100
101                 public static XmlWriter Create (XmlWriter output)
102                 {
103                         return Create (output, null);
104                 }
105
106                 public static XmlWriter Create (StringBuilder output)
107                 {
108                         return Create (output, null);
109                 }
110
111                 public static XmlWriter Create (Stream output, XmlWriterSettings settings)
112                 {
113                         Encoding enc = settings != null ? settings.Encoding : Encoding.UTF8;
114                         return Create (new StreamWriter (output, enc), settings);
115                 }
116
117                 public static XmlWriter Create (string outputFileName, XmlWriterSettings settings)
118                 {
119                         Encoding enc = settings != null ? settings.Encoding : Encoding.UTF8;
120                         return CreateTextWriter (new StreamWriter (outputFileName, false, enc), settings, true);
121                 }
122
123                 public static XmlWriter Create (StringBuilder output, XmlWriterSettings settings)
124                 {
125                         return Create (new StringWriter (output), settings);
126                 }
127
128                 public static XmlWriter Create (TextWriter output, XmlWriterSettings settings)
129                 {
130                         if (settings == null)
131                                 settings = new XmlWriterSettings ();
132                         return CreateTextWriter (output, settings, settings.CloseOutput);
133                 }
134
135                 public static XmlWriter Create (XmlWriter output, XmlWriterSettings settings)
136                 {
137                         if (settings == null)
138                                 settings = new XmlWriterSettings ();
139                         else
140                                 settings = settings.Clone ();
141
142                         var src = output.Settings;
143                         if (src == null) {
144                                 settings.ConformanceLevel = ConformanceLevel.Document; // Huh? Why??
145                                 output = new DefaultXmlWriter (output);
146 #if NET_4_5
147                                 settings.SetReadOnly ();
148 #endif
149                                 output.settings = settings;
150                         } else {
151                                 ConformanceLevel dst = src.ConformanceLevel;
152                                 switch (src.ConformanceLevel) {
153                                 case ConformanceLevel.Auto:
154                                         dst = settings.ConformanceLevel;
155                                         break;
156                                 case ConformanceLevel.Document:
157                                 case ConformanceLevel.Fragment:
158                                         if (settings.ConformanceLevel != ConformanceLevel.Auto)
159                                                 dst = settings.ConformanceLevel;
160                                         break;
161                                 }
162
163                                 settings.MergeFrom (src);
164
165 #if NET_4_5
166                                 settings.SetReadOnly ();
167 #endif
168
169                                 // It returns a new XmlWriter instance if 1) Settings is null, or 2) Settings ConformanceLevel (or might be other members as well) give significant difference.
170                                 if (src.ConformanceLevel != dst) {
171                                         output = new DefaultXmlWriter (output, false);
172                                         output.settings = settings;
173                                 }
174                         }
175
176                         return output;
177                 }
178
179                 private static XmlWriter CreateTextWriter (TextWriter writer, XmlWriterSettings settings, bool closeOutput)
180                 {
181                         if (settings == null)
182                                 settings = new XmlWriterSettings ();
183                         XmlTextWriter xtw = new XmlTextWriter (writer, settings, closeOutput);
184                         return Create (xtw, settings);
185                 }
186
187                 protected virtual void Dispose (bool disposing)
188                 {
189                         Close ();
190                 }
191
192 #if NET_4_0 || MOBILE
193                 public void Dispose ()
194 #else
195                 void IDisposable.Dispose() 
196 #endif
197                 {
198                         Dispose (false);
199                 }
200
201                 public abstract void Flush ();
202
203                 public abstract string LookupPrefix (string ns);
204
205                 private void WriteAttribute (XmlReader reader, bool defattr)
206                 {
207                         if (!defattr && reader.IsDefault)
208                                 return;
209
210                         WriteStartAttribute (reader.Prefix, reader.LocalName, reader.NamespaceURI);
211                         while (reader.ReadAttributeValue ()) {
212                                 switch (reader.NodeType) {
213                                 case XmlNodeType.Text:
214                                         WriteString (reader.Value);
215                                         break;
216                                 case XmlNodeType.EntityReference:
217                                         WriteEntityRef (reader.Name);
218                                         break;
219                                 }
220                         }
221                         WriteEndAttribute ();
222                 }
223
224                 public virtual void WriteAttributes (XmlReader reader, bool defattr)
225                 {
226                         if(reader == null)
227                                 throw new ArgumentException("null XmlReader specified.", "reader");
228
229                         switch (reader.NodeType) {
230                         case XmlNodeType.XmlDeclaration:
231                                 WriteAttributeString ("version", reader ["version"]);
232                                 if (reader ["encoding"] != null)
233                                         WriteAttributeString ("encoding", reader ["encoding"]);
234                                 if (reader ["standalone"] != null)
235                                         WriteAttributeString ("standalone", reader ["standalone"]);
236                                 break;
237                         case XmlNodeType.Element:
238                                 if (reader.MoveToFirstAttribute ())
239                                         goto case XmlNodeType.Attribute;
240                                 break;
241                         case XmlNodeType.Attribute:
242                                 do {
243                                         WriteAttribute (reader, defattr);
244                                 } while (reader.MoveToNextAttribute ());
245                                 reader.MoveToElement ();
246                                 break;
247                         default:
248                                 throw new XmlException("NodeType is not one of Element, Attribute, nor XmlDeclaration.");
249                         }
250                 }
251
252                 public void WriteAttributeString (string localName, string value)
253                 {
254                         WriteAttributeString ("", localName, null, value);
255                 }
256
257                 public void WriteAttributeString (string localName, string ns, string value)
258                 {
259                         WriteAttributeString ("", localName, ns, value);
260                 }
261
262                 public void WriteAttributeString (string prefix, string localName, string ns, string value)
263                 {
264                         // In MS.NET (1.0), this check is done *here*, not at WriteStartAttribute.
265                         // (XmlTextWriter.WriteStartAttribute("xmlns", "anyname", null) throws an exception.
266
267                         WriteStartAttribute (prefix, localName, ns);
268                         if (value != null && value.Length > 0)
269                                 WriteString (value);
270                         WriteEndAttribute ();
271                 }
272
273                 public abstract void WriteBase64 (byte[] buffer, int index, int count);
274
275                 public virtual void WriteBinHex (byte [] buffer, int index, int count)
276                 {
277                         StringWriter sw = new StringWriter ();
278                         XmlConvert.WriteBinHex (buffer, index, count, sw);
279                         WriteString (sw.ToString ());
280                 }
281
282                 public abstract void WriteCData (string text);
283
284                 public abstract void WriteCharEntity (char ch);
285
286                 public abstract void WriteChars (char[] buffer, int index, int count);
287
288                 public abstract void WriteComment (string text);
289
290                 public abstract void WriteDocType (string name, string pubid, string sysid, string subset);
291
292                 public void WriteElementString (string localName, string value)
293                 {
294                         WriteStartElement(localName);
295                         if (value != null && value.Length > 0)
296                                 WriteString(value);
297                         WriteEndElement();
298                 }
299
300                 public void WriteElementString (string localName, string ns, string value)
301                 {
302                         WriteStartElement(localName, ns);
303                         if (value != null && value.Length > 0)
304                                 WriteString(value);
305                         WriteEndElement();
306                 }
307
308                 public void WriteElementString (string prefix, string localName, string ns, string value)
309                 {
310                         WriteStartElement(prefix, localName, ns);
311                         if (value != null && value.Length > 0)
312                                 WriteString(value);
313                         WriteEndElement();
314                 }
315
316                 public abstract void WriteEndAttribute ();
317
318                 public abstract void WriteEndDocument ();
319
320                 public abstract void WriteEndElement ();
321
322                 public abstract void WriteEntityRef (string name);
323
324                 public abstract void WriteFullEndElement ();
325
326                 public virtual void WriteName (string name)
327                 {
328                         WriteNameInternal (name);
329                 }
330
331                 public virtual void WriteNmToken (string name)
332                 {
333                         WriteNmTokenInternal (name);
334                 }
335
336                 public virtual void WriteQualifiedName (string localName, string ns)
337                 {
338                         WriteQualifiedNameInternal (localName, ns);
339                 }
340
341                 internal void WriteNameInternal (string name)
342                 {
343                         switch (Settings.ConformanceLevel) {
344                         case ConformanceLevel.Document:
345                         case ConformanceLevel.Fragment:
346                                 XmlConvert.VerifyName (name);
347                                 break;
348                         }
349                         WriteString (name);
350                 }
351
352                 internal virtual void WriteNmTokenInternal (string name)
353                 {
354                         bool valid = true;
355                         switch (Settings.ConformanceLevel) {
356                         case ConformanceLevel.Document:
357                         case ConformanceLevel.Fragment:
358                                 valid = XmlChar.IsNmToken (name);
359                                         break;
360                         }
361                         if (!valid)
362                                 throw new ArgumentException ("Argument name is not a valid NMTOKEN.");
363                         WriteString (name);
364                 }
365
366                 internal void WriteQualifiedNameInternal (string localName, string ns)
367                 {
368                         if (localName == null || localName == String.Empty)
369                                 throw new ArgumentException ();
370                         if (ns == null)
371                                 ns = String.Empty;
372
373                         if (Settings != null) {
374                                 switch (Settings.ConformanceLevel) {
375                                 case ConformanceLevel.Document:
376                                 case ConformanceLevel.Fragment:
377                                         XmlConvert.VerifyNCName (localName);
378                                         break;
379                                 }
380                         }
381                         else
382                                 XmlConvert.VerifyNCName (localName);
383
384                         string prefix = ns.Length > 0 ? LookupPrefix (ns) : String.Empty;
385                         if (prefix == null)
386                                 throw new ArgumentException (String.Format ("Namespace '{0}' is not declared.", ns));
387
388                         if (prefix != String.Empty) {
389                                 WriteString (prefix);
390                                 WriteString (":");
391                                 WriteString (localName);
392                         }
393                         else
394                                 WriteString (localName);
395                 }
396
397                 public virtual void WriteNode (XPathNavigator navigator, bool defattr)
398                 {
399                         if (navigator == null)
400                                 throw new ArgumentNullException ("navigator");
401                         switch (navigator.NodeType) {
402                         case XPathNodeType.Attribute:
403                                 // no operation
404                                 break;
405                         case XPathNodeType.Namespace:
406                                 // no operation
407                                 break;
408                         case XPathNodeType.Text:
409                                 WriteString (navigator.Value);
410                                 break;
411                         case XPathNodeType.SignificantWhitespace:
412                                 WriteWhitespace (navigator.Value);
413                                 break;
414                         case XPathNodeType.Whitespace:
415                                 WriteWhitespace (navigator.Value);
416                                 break;
417                         case XPathNodeType.Comment:
418                                 WriteComment (navigator.Value);
419                                 break;
420                         case XPathNodeType.ProcessingInstruction:
421                                 WriteProcessingInstruction (navigator.Name, navigator.Value);
422                                 break;
423                         case XPathNodeType.Root:
424                                 if (navigator.MoveToFirstChild ()) {
425                                         do {
426                                                 WriteNode (navigator, defattr);
427                                         } while (navigator.MoveToNext ());
428                                         navigator.MoveToParent ();
429                                 }
430                                 break;
431                         case XPathNodeType.Element:
432                                 WriteStartElement (navigator.Prefix, navigator.LocalName, navigator.NamespaceURI);
433                                 if (navigator.MoveToFirstNamespace (XPathNamespaceScope.Local)) {
434                                         do {
435                                                 if (defattr || navigator.SchemaInfo == null || navigator.SchemaInfo.IsDefault)
436                                                         WriteAttributeString (navigator.Prefix,
437                                                                 navigator.LocalName == String.Empty ? "xmlns" : navigator.LocalName,
438                                                                 "http://www.w3.org/2000/xmlns/",
439                                                                 navigator.Value);
440                                         } while (navigator.MoveToNextNamespace (XPathNamespaceScope.Local));
441                                         navigator.MoveToParent ();
442                                 }
443                                 if (navigator.MoveToFirstAttribute ()) {
444                                         do {
445                                                 if (defattr || navigator.SchemaInfo == null || navigator.SchemaInfo.IsDefault)
446                                                         WriteAttributeString (navigator.Prefix, navigator.LocalName, navigator.NamespaceURI, navigator.Value);
447
448                                         } while (navigator.MoveToNextAttribute ());
449                                         navigator.MoveToParent ();
450                                 }
451                                 if (navigator.MoveToFirstChild ()) {
452                                         do {
453                                                 WriteNode (navigator, defattr);
454                                         } while (navigator.MoveToNext ());
455                                         navigator.MoveToParent ();
456                                 }
457                                 if (navigator.IsEmptyElement)
458                                         WriteEndElement ();
459                                 else
460                                         WriteFullEndElement ();
461                                 break;
462                         default:
463                                 throw new NotSupportedException ();
464                         }
465                 }
466
467                 public virtual void WriteNode (XmlReader reader, bool defattr)
468                 {
469                         if (reader == null)
470                                 throw new ArgumentException ();
471
472                         if (reader.ReadState == ReadState.Initial) {
473                                 reader.Read ();
474                                 do {
475                                         WriteNode (reader, defattr);
476                                 } while (!reader.EOF);
477                                 return;
478                         }
479
480                         switch (reader.NodeType) {
481                         case XmlNodeType.Element:
482                                 WriteStartElement (reader.Prefix, reader.LocalName, reader.NamespaceURI);
483 #if false
484                                 WriteAttributes (reader, defattr);
485                                 reader.MoveToElement ();
486 #else
487                                 // Well, I found that MS.NET took this way, since
488                                 // there was a error-prone SgmlReader that fails
489                                 // MoveToNextAttribute().
490                                 if (reader.HasAttributes) {
491                                         for (int i = 0; i < reader.AttributeCount; i++) {
492                                                 reader.MoveToAttribute (i);
493                                                 WriteAttribute (reader, defattr);
494                                         }
495                                         reader.MoveToElement ();
496                                 }
497 #endif
498                                 if (reader.IsEmptyElement)
499                                         WriteEndElement ();
500                                 else {
501                                         int depth = reader.Depth;
502                                         reader.Read ();
503                                         if (reader.NodeType != XmlNodeType.EndElement) {
504                                                 do {
505                                                         WriteNode (reader, defattr);
506                                                 } while (depth < reader.Depth);
507                                         }
508                                         WriteFullEndElement ();
509                                 }
510                                 break;
511                         // In case of XmlAttribute, don't proceed reader, and it will never be written.
512                         case XmlNodeType.Attribute:
513                                 return;
514                         case XmlNodeType.Text:
515                                 WriteString (reader.Value);
516                                 break;
517                         case XmlNodeType.CDATA:
518                                 WriteCData (reader.Value);
519                                 break;
520                         case XmlNodeType.EntityReference:
521                                 WriteEntityRef (reader.Name);
522                                 break;
523                         case XmlNodeType.XmlDeclaration:
524                                 // LAMESPEC: It means that XmlWriter implementation _must not_ check
525                                 // whether PI name is "xml" (it is XML error) or not.
526                         case XmlNodeType.ProcessingInstruction:
527                                 WriteProcessingInstruction (reader.Name, reader.Value);
528                                 break;
529                         case XmlNodeType.Comment:
530                                 WriteComment (reader.Value);
531                                 break;
532                         case XmlNodeType.DocumentType:
533                                 WriteDocType (reader.Name,
534                                         reader ["PUBLIC"], reader ["SYSTEM"], reader.Value);
535                                 break;
536                         case XmlNodeType.SignificantWhitespace:
537                                 goto case XmlNodeType.Whitespace;
538                         case XmlNodeType.Whitespace:
539                                 WriteWhitespace (reader.Value);
540                                 break;
541                         case XmlNodeType.EndElement:
542                                 WriteFullEndElement ();
543                                 break;
544                         case XmlNodeType.EndEntity:
545                                 break;
546                         case XmlNodeType.None:
547                                 break;  // Do nothing, nor reporting errors.
548                         default:
549                                 throw new XmlException ("Unexpected node " + reader.Name + " of type " + reader.NodeType);
550                         }
551                         reader.Read ();
552                 }
553
554                 public abstract void WriteProcessingInstruction (string name, string text);
555
556                 public abstract void WriteRaw (string data);
557
558                 public abstract void WriteRaw (char[] buffer, int index, int count);
559
560                 public void WriteStartAttribute (string localName)
561                 {
562                         WriteStartAttribute (null, localName, null);
563                 }
564
565                 public void WriteStartAttribute (string localName, string ns)
566                 {
567                         WriteStartAttribute (null, localName, ns);
568                 }
569
570                 public abstract void WriteStartAttribute (string prefix, string localName, string ns);
571
572                 public abstract void WriteStartDocument ();
573
574                 public abstract void WriteStartDocument (bool standalone);
575
576                 public void WriteStartElement (string localName)
577                 {
578                         WriteStartElement (null, localName, null);
579                 }
580
581                 public void WriteStartElement (string localName, string ns)
582                 {
583                         WriteStartElement (null, localName, ns);
584                 }
585
586                 public abstract void WriteStartElement (string prefix, string localName, string ns);
587
588                 public abstract void WriteString (string text);
589
590                 public abstract void WriteSurrogateCharEntity (char lowChar, char highChar);
591
592                 public abstract void WriteWhitespace (string ws);
593
594                 public virtual void WriteValue (bool value)
595                 {
596                         WriteString (XQueryConvert.BooleanToString (value));
597                 }
598
599                 public virtual void WriteValue (DateTime value)
600                 {
601                         WriteString (XmlConvert.ToString (value));
602                 }
603
604                 public virtual void WriteValue (decimal value)
605                 {
606                         WriteString (XQueryConvert.DecimalToString (value));
607                 }
608
609                 public virtual void WriteValue (double value)
610                 {
611                         WriteString (XQueryConvert.DoubleToString (value));
612                 }
613
614                 public virtual void WriteValue (int value)
615                 {
616                         WriteString (XQueryConvert.IntToString (value));
617                 }
618
619                 public virtual void WriteValue (long value)
620                 {
621                         WriteString (XQueryConvert.IntegerToString (value));
622                 }
623
624                 public virtual void WriteValue (object value)
625                 {
626                         if (value == null)
627                                 throw new ArgumentNullException ("value");
628
629                         if (value is string)
630                                 WriteString ((string) value);
631                         else if (value is bool)
632                                 WriteValue ((bool) value);
633                         else if (value is byte)
634                                 WriteValue ((int) value);
635                         else if (value is byte [])
636                                 WriteBase64 ((byte []) value, 0, ((byte []) value).Length);
637                         else if (value is char [])
638                                 WriteChars ((char []) value, 0, ((char []) value).Length);
639                         else if (value is DateTime)
640                                 WriteValue ((DateTime) value);
641                         else if (value is decimal)
642                                 WriteValue ((decimal) value);
643                         else if (value is double)
644                                 WriteValue ((double) value);
645                         else if (value is short)
646                                 WriteValue ((int) value);
647                         else if (value is int)
648                                 WriteValue ((int) value);
649                         else if (value is long)
650                                 WriteValue ((long) value);
651                         else if (value is float)
652                                 WriteValue ((float) value);
653                         else if (value is TimeSpan) // undocumented
654                                 WriteString (XmlConvert.ToString ((TimeSpan) value));
655                         else if (value is Uri)
656                                 WriteString (((Uri) value).ToString ());
657                         else if (value is XmlQualifiedName) {
658                                 XmlQualifiedName qname = (XmlQualifiedName) value;
659                                 if (!qname.Equals (XmlQualifiedName.Empty)) {
660                                         if (qname.Namespace.Length > 0 && LookupPrefix (qname.Namespace) == null)
661                                                 throw new InvalidCastException (String.Format ("The QName '{0}' cannot be written. No corresponding prefix is declared", qname));
662                                         WriteQualifiedName (qname.Name, qname.Namespace);
663                                 }
664                                 else
665                                         WriteString (String.Empty);
666                         }
667                         else if (value is IEnumerable) {
668                                 bool follow = false;
669                                 foreach (object obj in (IEnumerable) value) {
670                                         if (follow)
671                                                 WriteString (" ");
672                                         else
673                                                 follow = true;
674                                         WriteValue (obj);
675                                 }
676                         }
677                         else
678                                 throw new InvalidCastException (String.Format ("Type '{0}' cannot be cast to string", value.GetType ()));
679                 }
680
681                 public virtual void WriteValue (float value)
682                 {
683                         WriteString (XQueryConvert.FloatToString (value));
684                 }
685
686                 public virtual void WriteValue (string value)
687                 {
688                         WriteString (value);
689                 }
690
691 #if NET_4_5
692                 public virtual void WriteValue (DateTimeOffset value)
693                 {
694                         WriteString (XmlConvert.ToString (value));
695                 }
696 #endif
697
698                 #endregion
699
700 #if NET_4_5
701                 #region .NET 4.5 Async Methods
702
703                 bool asyncRunning;
704
705                 void StartAsync ()
706                 {
707                         if (!settings.Async)
708                                 throw new InvalidOperationException ("Set XmlWriterSettings.Async to true if you want to use Async Methods.");
709                         lock (this) {
710                                 if (asyncRunning)
711                                         throw new InvalidOperationException ("An asynchronous operation is already in progress.");
712                                 asyncRunning = true;
713                         }
714                 }
715
716                 public virtual Task FlushAsync ()
717                 {
718                         StartAsync ();
719                         return Task.Run (() => {
720                                 try {
721                                         Flush ();
722                                 } finally {
723                                         asyncRunning = false;
724                                 }
725                         });
726                 }
727
728                 public virtual Task WriteAttributesAsync (XmlReader reader, bool defattr)
729                 {
730                         StartAsync ();
731                         return Task.Run (() => {
732                                 try {
733                                         WriteAttributes (reader, defattr);
734                                 } finally {
735                                         asyncRunning = false;
736                                 }
737                         });
738                 }
739
740                 public Task WriteAttributeStringAsync (string prefix, string localName,
741                                                        string ns, string value)
742                 {
743                         StartAsync ();
744                         return Task.Run (() => {
745                                 try {
746                                         WriteAttributeString (prefix, localName, ns, value);
747                                 } finally {
748                                         asyncRunning = false;
749                                 }
750                         });
751                 }
752
753                 public virtual Task WriteBase64Async (byte[] buffer, int index, int count)
754                 {
755                         StartAsync ();
756                         return Task.Run (() => {
757                                 try {
758                                         WriteBase64 (buffer, index, count);
759                                 } finally {
760                                         asyncRunning = false;
761                                 }
762                         });
763                 }
764
765                 public virtual Task WriteBinHexAsync (byte[] buffer, int index, int count)
766                 {
767                         StartAsync ();
768                         return Task.Run (() => {
769                                 try {
770                                         WriteBinHex (buffer, index, count);
771                                 } finally {
772                                         asyncRunning = false;
773                                 }
774                         });
775                 }
776
777                 public virtual Task WriteCDataAsync (string text)
778                 {
779                         StartAsync ();
780                         return Task.Run (() => {
781                                 try {
782                                         WriteCData (text);
783                                 } finally {
784                                         asyncRunning = false;
785                                 }
786                         });
787                 }
788
789                 public virtual Task WriteCharEntityAsync (char ch)
790                 {
791                         StartAsync ();
792                         return Task.Run (() => {
793                                 try {
794                                         WriteCharEntity (ch);
795                                 } finally {
796                                         asyncRunning = false;
797                                 }
798                         });
799                 }
800
801                 public virtual Task WriteCharsAsync (char[] buffer, int index, int count)
802                 {
803                         StartAsync ();
804                         return Task.Run (() => {
805                                 try {
806                                         WriteChars (buffer, index, count);
807                                 } finally {
808                                         asyncRunning = false;
809                                 }
810                         });
811                 }
812
813                 public virtual Task WriteCommentAsync (string text)
814                 {
815                         StartAsync ();
816                         return Task.Run (() => {
817                                 try {
818                                         WriteComment (text);
819                                 } finally {
820                                         asyncRunning = false;
821                                 }
822                         });
823                 }
824
825                 public virtual Task WriteDocTypeAsync (string name, string pubid, string sysid, string subset)
826                 {
827                         StartAsync ();
828                         return Task.Run (() => {
829                                 try {
830                                         WriteDocType (name, pubid, sysid, subset);
831                                 } finally {
832                                         asyncRunning = false;
833                                 }
834                         });
835                 }
836
837                 public Task WriteElementStringAsync (string prefix, string localName, string ns, string value)
838                 {
839                         StartAsync ();
840                         return Task.Run (() => {
841                                 try {
842                                         WriteElementString (prefix, localName, ns, value);
843                                 } finally {
844                                         asyncRunning = false;
845                                 }
846                         });
847                 }
848
849                 protected internal virtual Task WriteEndAttributeAsync ()
850                 {
851                         StartAsync ();
852                         return Task.Run (() => {
853                                 try {
854                                         WriteEndAttribute ();
855                                 } finally {
856                                         asyncRunning = false;
857                                 }
858                         });
859                 }
860
861                 public virtual Task WriteEndDocumentAsync ()
862                 {
863                         StartAsync ();
864                         return Task.Run (() => {
865                                 try {
866                                         WriteEndDocument ();
867                                 } finally {
868                                         asyncRunning = false;
869                                 }
870                         });
871                 }
872
873                 public virtual Task WriteEndElementAsync ()
874                 {
875                         StartAsync ();
876                         return Task.Run (() => {
877                                 try {
878                                         WriteEndElement ();
879                                 } finally {
880                                         asyncRunning = false;
881                                 }
882                         });
883                 }
884
885                 public virtual Task WriteEntityRefAsync (string name)
886                 {
887                         StartAsync ();
888                         return Task.Run (() => {
889                                 try {
890                                         WriteEntityRef (name);
891                                 } finally {
892                                         asyncRunning = false;
893                                 }
894                         });
895                 }
896
897                 public virtual Task WriteFullEndElementAsync ()
898                 {
899                         StartAsync ();
900                         return Task.Run (() => {
901                                 try {
902                                         WriteFullEndElement ();
903                                 } finally {
904                                         asyncRunning = false;
905                                 }
906                         });
907                 }
908
909                 public virtual Task WriteNameAsync (string name)
910                 {
911                         StartAsync ();
912                         return Task.Run (() => {
913                                 try {
914                                         WriteName (name);
915                                 } finally {
916                                         asyncRunning = false;
917                                 }
918                         });
919                 }
920
921                 public virtual Task WriteNmTokenAsync (string name)
922                 {
923                         StartAsync ();
924                         return Task.Run (() => {
925                                 try {
926                                         WriteNmToken (name);
927                                 } finally {
928                                         asyncRunning = false;
929                                 }
930                         });
931                 }
932
933                 public virtual Task WriteNodeAsync (XmlReader reader, bool defattr)
934                 {
935                         StartAsync ();
936                         return Task.Run (() => {
937                                 try {
938                                         WriteNode (reader, defattr);
939                                 } finally {
940                                         asyncRunning = false;
941                                 }
942                         });
943                 }
944
945                 public virtual Task WriteNodeAsync (XPathNavigator navigator, bool defattr)
946                 {
947                         StartAsync ();
948                         return Task.Run (() => {
949                                 try {
950                                         WriteNode (navigator, defattr);
951                                 } finally {
952                                         asyncRunning = false;
953                                 }
954                         });
955                 }
956
957                 public virtual Task WriteProcessingInstructionAsync (string name, string text)
958                 {
959                         StartAsync ();
960                         return Task.Run (() => {
961                                 try {
962                                         WriteProcessingInstruction (name, text);
963                                 } finally {
964                                         asyncRunning = false;
965                                 }
966                         });
967                 }
968
969                 public virtual Task WriteQualifiedNameAsync (string localName, string ns)
970                 {
971                         StartAsync ();
972                         return Task.Run (() => {
973                                 try {
974                                         WriteQualifiedName (localName, ns);
975                                 } finally {
976                                         asyncRunning = false;
977                                 }
978                         });
979                 }
980
981                 public virtual Task WriteRawAsync (string data)
982                 {
983                         StartAsync ();
984                         return Task.Run (() => {
985                                 try {
986                                         WriteRaw (data);
987                                 } finally {
988                                         asyncRunning = false;
989                                 }
990                         });
991
992                 }
993
994                 public virtual Task WriteRawAsync (char[] buffer, int index, int count)
995                 {
996                         StartAsync ();
997                         return Task.Run (() => {
998                                 try {
999                                         WriteRaw (buffer, index, count);
1000                                 } finally {
1001                                         asyncRunning = false;
1002                                 }
1003                         });
1004                 }
1005
1006                 protected internal virtual Task WriteStartAttributeAsync (
1007                         string prefix, string localName, string ns)
1008                 {
1009                         StartAsync ();
1010                         return Task.Run (() => {
1011                                 try {
1012                                         WriteStartAttribute (prefix, localName, ns);
1013                                 } finally {
1014                                         asyncRunning = false;
1015                                 }
1016                         });
1017                 }
1018
1019                 public virtual Task WriteStartDocumentAsync ()
1020                 {
1021                         StartAsync ();
1022                         return Task.Run (() => {
1023                                 try {
1024                                         WriteStartDocument ();
1025                                 } finally {
1026                                         asyncRunning = false;
1027                                 }
1028                         });
1029                 }
1030
1031                 public virtual Task WriteStartDocumentAsync (bool standalone)
1032                 {
1033                         StartAsync ();
1034                         return Task.Run (() => {
1035                                 try {
1036                                         WriteStartDocument (standalone);
1037                                 } finally {
1038                                         asyncRunning = false;
1039                                 }
1040                         });
1041                 }
1042
1043                 public virtual Task WriteStartElementAsync (string prefix, string localName, string ns)
1044                 {
1045                         StartAsync ();
1046                         return Task.Run (() => {
1047                                 try {
1048                                         WriteStartElement (prefix, localName, ns);
1049                                 } finally {
1050                                         asyncRunning = false;
1051                                 }
1052                         });
1053                 }
1054
1055                 public virtual Task WriteStringAsync (string text)
1056                 {
1057                         StartAsync ();
1058                         return Task.Run (() => {
1059                                 try {
1060                                         WriteString (text);
1061                                 } finally {
1062                                         asyncRunning = false;
1063                                 }
1064                         });
1065                 }
1066
1067                 public virtual Task WriteSurrogateCharEntityAsync (char lowChar, char highChar)
1068                 {
1069                         StartAsync ();
1070                         return Task.Run (() => {
1071                                 try {
1072                                         WriteSurrogateCharEntity (lowChar, highChar);
1073                                 } finally {
1074                                         asyncRunning = false;
1075                                 }
1076                         });
1077                 }
1078
1079                 public virtual Task WriteWhitespaceAsync (string ws)
1080                 {
1081                         StartAsync ();
1082                         return Task.Run (() => {
1083                                 try {
1084                                         WriteWhitespace (ws);
1085                                 } finally {
1086                                         asyncRunning = false;
1087                                 }
1088                         });
1089                 }
1090
1091                 #endregion
1092 #endif
1093         }
1094 }