Merge pull request #439 from mono-soc-2012/garyb/iconfix
[mono.git] / mcs / class / System.XML / System.Xml / XmlReader.cs
1 //
2 // XmlReader.cs
3 //
4 // Authors:
5 //      Jason Diamond (jason@injektilo.org)
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //      Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
8 //
9 // (C) 2001, 2002 Jason Diamond  http://injektilo.org/
10 // (c) 2002 Ximian, Inc. (http://www.ximian.com)
11 // (C) 2003 Atsushi Enomoto
12 //
13
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34 using System.Collections;
35 using System.Diagnostics;
36 using System.IO;
37 using System.Text;
38 #if !MOONLIGHT
39 using System.Xml.Schema; // only required for NET_2_0 (SchemaInfo)
40 using System.Xml.Serialization; // only required for NET_2_0 (SchemaInfo)
41 using Mono.Xml.Schema; // only required for NET_2_0
42 #endif
43 using Mono.Xml; // only required for NET_2_0
44 #if NET_4_5
45 using System.Threading;
46 using System.Threading.Tasks;
47 #endif
48
49 namespace System.Xml
50 {
51 #if NET_2_0
52         public abstract class XmlReader : IDisposable
53 #else
54         public abstract class XmlReader
55 #endif
56         {
57                 private StringBuilder readStringBuffer;
58                 private XmlReaderBinarySupport binary;
59 #if NET_2_0
60                 private XmlReaderSettings settings;
61 #endif
62
63                 #region Constructor
64
65                 protected XmlReader ()
66                 {
67                 }
68
69                 #endregion
70
71                 #region Properties
72
73                 public abstract int AttributeCount { get; }
74
75                 public abstract string BaseURI { get; }
76
77                 internal XmlReaderBinarySupport Binary {
78                         get { return binary; }
79                 }
80
81                 internal XmlReaderBinarySupport.CharGetter BinaryCharGetter {
82                         get { return binary != null ? binary.Getter : null; }
83                         set {
84                                 if (binary == null)
85                                         binary = new XmlReaderBinarySupport (this);
86                                 binary.Getter = value;
87                         }
88                 }
89
90 #if NET_2_0
91                 // To enable it internally in sys.xml, just insert these
92                 // two lines into Read():
93                 //
94                 //      #if NET_2_0
95                 //      if (Binary != null)
96                 //              Binary.Reset ();
97                 //      #endif
98                 //
99                 public virtual bool CanReadBinaryContent {
100                         get { return false; }
101                 }
102
103                 public virtual bool CanReadValueChunk {
104                         get { return false; }
105                 }
106 #else
107                 internal virtual bool CanReadBinaryContent {
108                         get { return false; }
109                 }
110
111                 internal virtual bool CanReadValueChunk {
112                         get { return false; }
113                 }
114 #endif
115
116                 public virtual bool CanResolveEntity
117                 {
118                         get     { return false; }
119                 }
120
121                 public abstract int Depth { get; }
122
123                 public abstract bool EOF { get; }
124
125                 public virtual bool HasAttributes
126                 {
127                         get { return AttributeCount > 0; }
128                 }
129
130 #if NET_4_0
131                 public virtual bool HasValue {
132                         get {
133                                 switch (NodeType) {
134                                 case XmlNodeType.Attribute:
135                                 case XmlNodeType.Comment:
136                                 case XmlNodeType.ProcessingInstruction:
137                                 case XmlNodeType.SignificantWhitespace:
138                                 case XmlNodeType.CDATA:
139                                 case XmlNodeType.Text:
140                                 case XmlNodeType.Whitespace:
141                                 case XmlNodeType.XmlDeclaration:
142                                         return true;
143                                 }
144                                 return false;
145                         }
146                 }
147 #else
148                 public abstract bool HasValue { get; }
149 #endif
150
151                 public abstract bool IsEmptyElement { get; }
152
153 #if NET_2_0
154                 public virtual bool IsDefault {
155                         get { return false; }
156                 }
157
158                 public virtual string this [int i] {
159                         get { return GetAttribute (i); }
160                 }
161
162                 public virtual string this [string name] {
163                         get { return GetAttribute (name); }
164                 }
165
166                 public virtual string this [string name, string namespaceURI] {
167                         get { return GetAttribute (name, namespaceURI); }
168                 }
169 #else
170                 public abstract bool IsDefault { get; }
171
172                 public abstract string this [int i] { get; }
173
174                 public abstract string this [string name] { get; }
175
176                 public abstract string this [string localName, string namespaceName] { get; }
177 #endif
178
179                 public abstract string LocalName { get; }
180
181 #if NET_2_0
182                 public virtual string Name {
183                         get {
184                                 return Prefix.Length > 0 ?
185                                         String.Concat (Prefix, ":", LocalName) :
186                                         LocalName;
187                         }
188                 }
189 #else
190                 public abstract string Name { get; }
191 #endif
192
193                 public abstract string NamespaceURI { get; }
194
195                 public abstract XmlNameTable NameTable { get; }
196
197                 public abstract XmlNodeType NodeType { get; }
198
199                 public abstract string Prefix { get; }
200
201 #if NET_2_0
202                 public virtual char QuoteChar {
203                         get { return '\"'; }
204                 }
205 #else
206                 public abstract char QuoteChar { get; }
207 #endif
208
209                 public abstract ReadState ReadState { get; }
210
211 #if NET_2_0
212 #if !MOONLIGHT
213                 public virtual IXmlSchemaInfo SchemaInfo {
214                         get { return null; }
215                 }
216 #endif
217
218                 public virtual XmlReaderSettings Settings {
219                         get { return settings; }
220                 }
221 #endif
222
223                 public abstract string Value { get; }
224
225 #if NET_2_0
226                 public virtual string XmlLang {
227                         get { return String.Empty; }
228                 }
229
230                 public virtual XmlSpace XmlSpace {
231                         get { return XmlSpace.None; }
232                 }
233 #else
234                 public abstract string XmlLang { get; }
235
236                 public abstract XmlSpace XmlSpace { get; }
237 #endif
238
239                 #endregion
240
241                 #region Methods
242
243 #if NET_4_5
244                 public virtual void Close ()
245                 {
246                         if (asyncRunning)
247                                 throw new InvalidOperationException ("An asynchronous operation is already in progress.");
248                 }
249 #else
250                 public abstract void Close ();
251 #endif
252
253 #if NET_2_0
254                 private static XmlNameTable PopulateNameTable (
255                         XmlReaderSettings settings)
256                 {
257                         XmlNameTable nameTable = settings.NameTable;
258                         if (nameTable == null)
259                                 nameTable = new NameTable ();
260                         return nameTable;
261                 }
262
263                 private static XmlParserContext PopulateParserContext (
264                         XmlReaderSettings settings, string baseUri)
265                 {
266                         XmlNameTable nt = PopulateNameTable (settings);
267                         return new XmlParserContext (nt,
268                                 new XmlNamespaceManager (nt),
269                                 null,
270                                 null,
271                                 null,
272                                 null,
273                                 baseUri,
274                                 null,
275                                 XmlSpace.None,
276                                 null);
277                 }
278
279                 private static XmlNodeType GetNodeType (
280                         XmlReaderSettings settings)
281                 {
282                         ConformanceLevel level = settings != null ? settings.ConformanceLevel : ConformanceLevel.Auto;
283                         return
284                                 level == ConformanceLevel.Fragment ?
285                                 XmlNodeType.Element :
286                                 XmlNodeType.Document;
287                 }
288
289                 public static XmlReader Create (Stream input)
290                 {
291                         return Create (input, null);
292                 }
293
294                 public static XmlReader Create (string inputUri)
295                 {
296                         return Create (inputUri, null);
297                 }
298
299                 public static XmlReader Create (TextReader input)
300                 {
301                         return Create (input, null);
302                 }
303
304                 public static XmlReader Create (string inputUri, XmlReaderSettings settings)
305                 {
306                         return Create (inputUri, settings, null);
307                 }
308
309                 public static XmlReader Create (Stream input, XmlReaderSettings settings)
310                 {
311                         return Create (input, settings, String.Empty);
312                 }
313
314                 public static XmlReader Create (TextReader input, XmlReaderSettings settings)
315                 {
316                         return Create (input, settings, String.Empty);
317                 }
318
319                 static XmlReaderSettings PopulateSettings (XmlReaderSettings src)
320                 {
321                         XmlReaderSettings copy;
322                         if (src == null)
323                                 copy = new XmlReaderSettings ();
324                         else
325                                 copy = src.Clone ();
326 #if NET_4_5
327                         copy.SetReadOnly ();
328 #endif
329                         return copy;
330                 }
331
332                 static XmlReaderSettings PopulateSettings (XmlReader reader, XmlReaderSettings src)
333                 {
334                         XmlReaderSettings copy;
335                         if (src == null)
336                                 copy = new XmlReaderSettings ();
337                         else
338                                 copy = src.Clone ();
339 #if NET_4_5
340                         if (reader.Settings != null)
341                                 copy.Async = reader.Settings.Async;
342                         copy.SetReadOnly ();
343 #endif
344                         return copy;
345                 }
346
347                 public static XmlReader Create (Stream input, XmlReaderSettings settings, string baseUri)
348                 {
349                         settings = PopulateSettings (settings);
350                         return Create (input, settings,
351                                 PopulateParserContext (settings, baseUri));
352                 }
353
354                 public static XmlReader Create (TextReader input, XmlReaderSettings settings, string baseUri)
355                 {
356                         settings = PopulateSettings (settings);
357                         return Create (input, settings,
358                                 PopulateParserContext (settings, baseUri));
359                 }
360
361                 public static XmlReader Create (XmlReader reader, XmlReaderSettings settings)
362                 {
363                         settings = PopulateSettings (reader, settings);
364                         XmlReader r = CreateFilteredXmlReader (reader, settings);
365                         r.settings = settings;
366                         return r;
367                 }
368
369                 public static XmlReader Create (string inputUri, XmlReaderSettings settings, XmlParserContext inputContext)
370                 {
371                         settings = PopulateSettings (settings);
372                         bool closeInputBak = settings.CloseInput;
373                         try {
374                                 settings.CloseInput = true; // forced. See XmlReaderCommonTests.CreateFromUrlClose().
375                                 if (inputContext == null)
376                                         inputContext = PopulateParserContext (settings, inputUri);
377                                 XmlTextReader xtr = new XmlTextReader (false, settings.XmlResolver, inputUri, GetNodeType (settings), inputContext);
378                                 XmlReader ret = CreateCustomizedTextReader (xtr, settings);
379                                 return ret;
380                         } finally {
381                                 settings.CloseInput = closeInputBak;
382                         }
383                 }
384
385                 public static XmlReader Create (Stream input, XmlReaderSettings settings, XmlParserContext inputContext)
386                 {
387                         settings = PopulateSettings (settings);
388                         if (inputContext == null)
389                                 inputContext = PopulateParserContext (settings, String.Empty);
390                         return CreateCustomizedTextReader (new XmlTextReader (input, GetNodeType (settings), inputContext), settings);
391                 }
392
393                 public static XmlReader Create (TextReader input, XmlReaderSettings settings, XmlParserContext inputContext)
394                 {
395                         settings = PopulateSettings (settings);
396                         if (inputContext == null)
397                                 inputContext = PopulateParserContext (settings, String.Empty);
398                         return CreateCustomizedTextReader (new XmlTextReader (inputContext.BaseURI, input, GetNodeType (settings), inputContext), settings);
399                 }
400
401                 private static XmlReader CreateCustomizedTextReader (XmlTextReader reader, XmlReaderSettings settings)
402                 {
403                         reader.XmlResolver = settings.XmlResolver;
404                         // Normalization is set true by default.
405                         reader.Normalization = true;
406                         reader.EntityHandling = EntityHandling.ExpandEntities;
407
408                         if (settings.ProhibitDtd)
409                                 reader.ProhibitDtd = true;
410
411                         if (!settings.CheckCharacters)
412                                 reader.CharacterChecking = false;
413
414                         // I guess it might be changed in 2.0 RTM to set true
415                         // as default, or just disappear. It goes against
416                         // XmlTextReader's default usage and users will have 
417                         // to close input manually (that's annoying). Moreover,
418                         // MS XmlTextReader consumes text input more than 
419                         // actually read and users can acquire those extra
420                         // consumption by GetRemainder() that returns different
421                         // TextReader.
422                         reader.CloseInput = settings.CloseInput;
423
424                         // I would like to support it in detail later;
425                         // MSDN description looks source of confusion. We don't
426                         // need examples, but precise list of how it works.
427                         reader.Conformance = settings.ConformanceLevel;
428
429                         reader.AdjustLineInfoOffset (settings.LineNumberOffset,
430                                 settings.LinePositionOffset);
431
432                         if (settings.NameTable != null)
433                                 reader.SetNameTable (settings.NameTable);
434
435                         XmlReader r = CreateFilteredXmlReader (reader, settings);
436                         r.settings = settings;
437                         return r;
438                 }
439
440                 private static XmlReader CreateFilteredXmlReader (XmlReader reader, XmlReaderSettings settings)
441                 {
442                         ConformanceLevel conf = ConformanceLevel.Auto;
443                         if (reader is XmlTextReader)
444                                 conf = ((XmlTextReader) reader).Conformance;
445                         else if (reader.Settings != null)
446                                 conf = reader.Settings.ConformanceLevel;
447                         else
448                                 conf = settings.ConformanceLevel;
449                         if (settings.ConformanceLevel != ConformanceLevel.Auto &&
450                                 conf != settings.ConformanceLevel)
451                                 throw new InvalidOperationException (String.Format ("ConformanceLevel cannot be overwritten by a wrapping XmlReader. The source reader has {0}, while {1} is specified.", conf, settings.ConformanceLevel));
452                         settings.ConformanceLevel = conf;
453
454                         reader = CreateValidatingXmlReader (reader, settings);
455
456                         if ( settings.IgnoreComments ||
457                              settings.IgnoreProcessingInstructions ||
458                              settings.IgnoreWhitespace)
459                                 return new XmlFilterReader (reader, settings);
460                         else {
461                                 reader.settings = settings;
462                                 return reader;
463                         }
464                 }
465
466                 private static XmlReader CreateValidatingXmlReader (XmlReader reader, XmlReaderSettings settings)
467                 {
468 #if MOONLIGHT
469                         return reader;
470 #else
471                         XmlValidatingReader xvr = null;
472                         switch (settings.ValidationType) {
473                         // Auto and XDR are obsoleted in 2.0 and therefore ignored.
474                         default:
475                                 return reader;
476                         case ValidationType.DTD:
477                                 xvr = new XmlValidatingReader (reader);
478                                 xvr.XmlResolver = settings.XmlResolver;
479                                 xvr.ValidationType = ValidationType.DTD;
480                                 break;
481                         case ValidationType.Schema:
482                                 return new XmlSchemaValidatingReader (reader, settings);
483                         }
484
485                         // Actually I don't think they are treated in DTD validation though...
486                         if ((settings.ValidationFlags & XmlSchemaValidationFlags.ProcessIdentityConstraints) == 0)
487                                 throw new NotImplementedException ();
488                         //if ((settings.ValidationFlags & XmlSchemaValidationFlags.ProcessInlineSchema) != 0)
489                         //      throw new NotImplementedException ();
490                         //if ((settings.ValidationFlags & XmlSchemaValidationFlags.ProcessSchemaLocation) != 0)
491                         //      throw new NotImplementedException ();
492                         //if ((settings.ValidationFlags & XmlSchemaValidationFlags.ReportValidationWarnings) == 0)
493                         //      throw new NotImplementedException ();
494
495                         return xvr != null ? xvr : reader;
496 #endif
497                 }
498
499 #if NET_4_0 || MOBILE
500                 public void Dispose ()
501 #else
502                 void IDisposable.Dispose() 
503 #endif
504                 {
505                         Dispose (false);
506                 }
507
508                 protected virtual void Dispose (bool disposing)
509                 {
510                         if (ReadState != ReadState.Closed)
511                                 Close ();
512                 }
513 #endif
514
515                 public abstract string GetAttribute (int i);
516
517                 public abstract string GetAttribute (string name);
518
519                 public abstract string GetAttribute (string name, string namespaceURI);
520
521                 public static bool IsName (string str)
522                 {
523                         return str != null && XmlChar.IsName (str);
524                 }
525
526                 public static bool IsNameToken (string str)
527                 {
528                         return str != null && XmlChar.IsNmToken (str);
529                 }
530
531                 public virtual bool IsStartElement ()
532                 {
533                         return (MoveToContent () == XmlNodeType.Element);
534                 }
535
536                 public virtual bool IsStartElement (string name)
537                 {
538                         if (!IsStartElement ())
539                                 return false;
540
541                         return (Name == name);
542                 }
543
544                 public virtual bool IsStartElement (string localname, string ns)
545                 {
546                         if (!IsStartElement ())
547                                 return false;
548
549                         return (LocalName == localname && NamespaceURI == ns);
550                 }
551
552                 public abstract string LookupNamespace (string prefix);
553
554 #if NET_2_0
555                 public virtual void MoveToAttribute (int i)
556                 {
557                         if (i >= AttributeCount)
558                                 throw new ArgumentOutOfRangeException ();
559                         MoveToFirstAttribute ();
560                         for (int a = 0; a < i; a++)
561                                 MoveToNextAttribute ();
562                 }
563 #else
564                 public abstract void MoveToAttribute (int i);
565 #endif
566
567                 public abstract bool MoveToAttribute (string name);
568
569                 public abstract bool MoveToAttribute (string name, string ns);
570
571                 private bool IsContent (XmlNodeType nodeType)
572                 {
573                         /* MS doc says:
574                          * (non-white space text, CDATA, Element, EndElement, EntityReference, or EndEntity)
575                          */
576                         switch (nodeType) {
577                         case XmlNodeType.Text:
578                                 return true;
579                         case XmlNodeType.CDATA:
580                                 return true;
581                         case XmlNodeType.Element:
582                                 return true;
583                         case XmlNodeType.EndElement:
584                                 return true;
585                         case XmlNodeType.EntityReference:
586                                 return true;
587                         case XmlNodeType.EndEntity:
588                                 return true;
589                         }
590
591                         return false;
592                 }
593
594                 public virtual XmlNodeType MoveToContent ()
595                 {
596                         switch (ReadState) {
597                         case ReadState.Initial:
598                         case ReadState.Interactive:
599                                 break;
600                         default:
601                                 return NodeType;
602                         }
603
604                         if (NodeType == XmlNodeType.Attribute)
605                                 MoveToElement ();
606
607                         do {
608                                 if (IsContent (NodeType))
609                                         return NodeType;
610                                 Read ();
611                         } while (!EOF);
612                         return XmlNodeType.None;
613                 }
614
615                 public abstract bool MoveToElement ();
616
617                 public abstract bool MoveToFirstAttribute ();
618
619                 public abstract bool MoveToNextAttribute ();
620
621                 public abstract bool Read ();
622
623                 public abstract bool ReadAttributeValue ();
624
625                 public virtual string ReadElementString ()
626                 {
627                         if (MoveToContent () != XmlNodeType.Element) {
628                                 string error = String.Format ("'{0}' is an invalid node type.",
629                                                               NodeType.ToString ());
630                                 throw XmlError (error);
631                         }
632
633                         string result = String.Empty;
634                         if (!IsEmptyElement) {
635                                 Read ();
636                                 result = ReadString ();
637                                 if (NodeType != XmlNodeType.EndElement) {
638                                         string error = String.Format ("'{0}' is an invalid node type.",
639                                                                       NodeType.ToString ());
640                                         throw XmlError (error);
641                                 }
642                         }
643
644                         Read ();
645                         return result;
646                 }
647
648                 public virtual string ReadElementString (string name)
649                 {
650                         if (MoveToContent () != XmlNodeType.Element) {
651                                 string error = String.Format ("'{0}' is an invalid node type.",
652                                                               NodeType.ToString ());
653                                 throw XmlError (error);
654                         }
655
656                         if (name != Name) {
657                                 string error = String.Format ("The {0} tag from namespace {1} is expected.",
658                                                               Name, NamespaceURI);
659                                 throw XmlError (error);
660                         }
661
662                         string result = String.Empty;
663                         if (!IsEmptyElement) {
664                                 Read ();
665                                 result = ReadString ();
666                                 if (NodeType != XmlNodeType.EndElement) {
667                                         string error = String.Format ("'{0}' is an invalid node type.",
668                                                                       NodeType.ToString ());
669                                         throw XmlError (error);
670                                 }
671                         }
672
673                         Read ();
674                         return result;
675                 }
676
677                 public virtual string ReadElementString (string localname, string ns)
678                 {
679                         if (MoveToContent () != XmlNodeType.Element) {
680                                 string error = String.Format ("'{0}' is an invalid node type.",
681                                                               NodeType.ToString ());
682                                 throw XmlError (error);
683                         }
684
685                         if (localname != LocalName || NamespaceURI != ns) {
686                                 string error = String.Format ("The {0} tag from namespace {1} is expected.",
687                                                               LocalName, NamespaceURI);
688                                 throw XmlError (error);
689                         }
690
691                         string result = String.Empty;
692                         if (!IsEmptyElement) {
693                                 Read ();
694                                 result = ReadString ();
695                                 if (NodeType != XmlNodeType.EndElement) {
696                                         string error = String.Format ("'{0}' is an invalid node type.",
697                                                                       NodeType.ToString ());
698                                         throw XmlError (error);
699                                 }
700                         }
701
702                         Read ();
703                         return result;
704                 }
705
706                 public virtual void ReadEndElement ()
707                 {
708                         if (MoveToContent () != XmlNodeType.EndElement) {
709                                 string error = String.Format ("'{0}' is an invalid node type.",
710                                                               NodeType.ToString ());
711                                 throw XmlError (error);
712                         }
713
714                         Read ();
715                 }
716
717                 public virtual string ReadInnerXml ()
718                 {
719                         if (ReadState != ReadState.Interactive || NodeType == XmlNodeType.EndElement)
720                                 return String.Empty;
721
722                         if (IsEmptyElement) {
723                                 Read ();
724                                 return String.Empty;
725                         }
726                         StringWriter sw = new StringWriter ();
727                         XmlTextWriter xtw = new XmlTextWriter (sw);
728                         if (NodeType == XmlNodeType.Element) {
729                                 int startDepth = Depth;
730                                 Read ();
731                                 while (startDepth < Depth) {
732                                         if (ReadState != ReadState.Interactive)
733                                                 throw XmlError ("Unexpected end of the XML reader.");
734                                         xtw.WriteNode (this, false);
735                                 }
736                                 // reader is now end element, then proceed once more.
737                                 Read ();
738                         }
739                         else
740                                 xtw.WriteNode (this, false);
741
742                         return sw.ToString ();
743                 }
744
745                 public virtual string ReadOuterXml ()
746                 {
747                         if (ReadState != ReadState.Interactive || NodeType == XmlNodeType.EndElement)
748                                 return String.Empty;
749
750                         switch (NodeType) {
751                         case XmlNodeType.Element:
752                         case XmlNodeType.Attribute:
753                                 StringWriter sw = new StringWriter ();
754                                 XmlTextWriter xtw = new XmlTextWriter (sw);
755                                 xtw.WriteNode (this, false);
756                                 return sw.ToString ();
757                         default:
758                                 Skip ();
759                                 return String.Empty;
760                         }
761                 }
762
763                 public virtual void ReadStartElement ()
764                 {
765                         if (MoveToContent () != XmlNodeType.Element) {
766                                 string error = String.Format ("'{0}' is an invalid node type.",
767                                                               NodeType.ToString ());
768                                 throw XmlError (error);
769                         }
770
771                         Read ();
772                 }
773
774                 public virtual void ReadStartElement (string name)
775                 {
776                         if (MoveToContent () != XmlNodeType.Element) {
777                                 string error = String.Format ("'{0}' is an invalid node type.",
778                                                               NodeType.ToString ());
779                                 throw XmlError (error);
780                         }
781
782                         if (name != Name) {
783                                 string error = String.Format ("The {0} tag from namespace {1} is expected.",
784                                                               Name, NamespaceURI);
785                                 throw XmlError (error);
786                         }
787
788                         Read ();
789                 }
790
791                 public virtual void ReadStartElement (string localname, string ns)
792                 {
793                         if (MoveToContent () != XmlNodeType.Element) {
794                                 string error = String.Format ("'{0}' is an invalid node type.",
795                                                               NodeType.ToString ());
796                                 throw XmlError (error);
797                         }
798
799                         if (localname != LocalName || NamespaceURI != ns) {
800                                 string error = String.Format ("Expecting {0} tag from namespace {1}, got {2} and {3} instead",
801                                                               localname, ns,
802                                                               LocalName, NamespaceURI);
803                                 throw XmlError (error);
804                         }
805
806                         Read ();
807                 }
808
809                 public virtual string ReadString ()
810                 {
811                         if (readStringBuffer == null)
812                                 readStringBuffer = new StringBuilder ();
813                         readStringBuffer.Length = 0;
814
815                         MoveToElement ();
816
817                         switch (NodeType) {
818                         default:
819                                 return String.Empty;
820                         case XmlNodeType.Element:
821                                 if (IsEmptyElement)
822                                         return String.Empty;
823                                 do {
824                                         Read ();
825                                         switch (NodeType) {
826                                         case XmlNodeType.Text:
827                                         case XmlNodeType.CDATA:
828                                         case XmlNodeType.Whitespace:
829                                         case XmlNodeType.SignificantWhitespace:
830                                                 readStringBuffer.Append (Value);
831                                                 continue;
832                                         }
833                                         break;
834                                 } while (true);
835                                 break;
836                         case XmlNodeType.Text:
837                         case XmlNodeType.CDATA:
838                         case XmlNodeType.Whitespace:
839                         case XmlNodeType.SignificantWhitespace:
840                                 do {
841                                         switch (NodeType) {
842                                         case XmlNodeType.Text:
843                                         case XmlNodeType.CDATA:
844                                         case XmlNodeType.Whitespace:
845                                         case XmlNodeType.SignificantWhitespace:
846                                                 readStringBuffer.Append (Value);
847                                                 Read ();
848                                                 continue;
849                                         }
850                                         break;
851                                 } while (true);
852                                 break;
853                         }
854                         string ret = readStringBuffer.ToString ();
855                         readStringBuffer.Length = 0;
856                         return ret;
857                 }
858
859 #if NET_2_0
860                 public virtual Type ValueType {
861                         get { return typeof (string); }
862                 }
863
864                 public virtual bool ReadToDescendant (string name)
865                 {
866                         if (ReadState == ReadState.Initial) {
867                                 MoveToContent ();
868                                 if (IsStartElement (name))
869                                         return true;
870                         }
871                         if (NodeType != XmlNodeType.Element || IsEmptyElement)
872                                 return false;
873                         int depth = Depth;
874                         for (Read (); depth < Depth; Read ())
875                                 if (NodeType == XmlNodeType.Element && name == Name)
876                                         return true;
877                         return false;
878                 }
879
880                 public virtual bool ReadToDescendant (string localName, string namespaceURI)
881                 {
882                         if (ReadState == ReadState.Initial) {
883                                 MoveToContent ();
884                                 if (IsStartElement (localName, namespaceURI))
885                                         return true;
886                         }
887                         if (NodeType != XmlNodeType.Element || IsEmptyElement)
888                                 return false;
889                         int depth = Depth;
890                         for (Read (); depth < Depth; Read ())
891                                 if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
892                                         return true;
893                         return false;
894                 }
895
896                 public virtual bool ReadToFollowing (string name)
897                 {
898                         while (Read ())
899                                 if (NodeType == XmlNodeType.Element && name == Name)
900                                         return true;
901                         return false;
902                 }
903
904                 public virtual bool ReadToFollowing (string localName, string namespaceURI)
905                 {
906                         while (Read ())
907                                 if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
908                                         return true;
909                         return false;
910                 }
911
912                 public virtual bool ReadToNextSibling (string name)
913                 {
914                         if (ReadState != ReadState.Interactive)
915                                 return false;
916                         MoveToElement ();
917                         int depth = Depth;
918                         Skip ();
919                         for (; !EOF && depth <= Depth; Skip ())
920                                 if (NodeType == XmlNodeType.Element && name == Name)
921                                         return true;
922                         return false;
923                 }
924
925                 public virtual bool ReadToNextSibling (string localName, string namespaceURI)
926                 {
927                         if (ReadState != ReadState.Interactive)
928                                 return false;
929                         int depth = Depth;
930                         Skip ();
931                         for (; !EOF && depth <= Depth; Skip ())
932                                 if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
933                                         return true;
934                         return false;
935                 }
936
937                 public virtual XmlReader ReadSubtree ()
938                 {
939                         if (NodeType != XmlNodeType.Element)
940                                 throw new InvalidOperationException (String.Format ("ReadSubtree() can be invoked only when the reader is positioned on an element. Current node is {0}. {1}", NodeType, GetLocation ()));
941                         return new SubtreeXmlReader (this);
942                 }
943
944                 private string ReadContentString ()
945                 {
946                         // The latter condition indicates that this XmlReader is on an attribute value
947                         // (HasAttributes is to indicate it is on attribute value).
948                         if (NodeType == XmlNodeType.Attribute || NodeType != XmlNodeType.Element && HasAttributes)
949                                 return Value;
950                         return ReadContentString (true);
951                 }
952
953                 private string ReadContentString (bool isText)
954                 {
955                         if (isText) {
956                                 switch (NodeType) {
957                                 case XmlNodeType.Text:
958                                 case XmlNodeType.SignificantWhitespace:
959                                 case XmlNodeType.Whitespace:
960                                 case XmlNodeType.CDATA:
961                                         break;
962                                 case XmlNodeType.Element:
963                                         throw new InvalidOperationException (String.Format ("Node type {0} is not supported in this operation.{1}", NodeType, GetLocation ()));
964                                 default:
965                                         return String.Empty;
966                                 }
967                         }
968
969                         string value = String.Empty;
970                         do {
971                                 switch (NodeType) {
972                                 case XmlNodeType.Element:
973                                         if (isText)
974                                                 return value;
975                                         throw XmlError ("Child element is not expected in this operation.");
976                                 case XmlNodeType.EndElement:
977                                         return value;
978                                 case XmlNodeType.Text:
979                                 case XmlNodeType.CDATA:
980                                 case XmlNodeType.SignificantWhitespace:
981                                 case XmlNodeType.Whitespace:
982                                         value += Value;
983                                         break;
984                                 }
985                         } while (Read ());
986                         throw XmlError ("Unexpected end of document.");
987                 }
988
989                 string GetLocation ()
990                 {
991                         IXmlLineInfo li = this as IXmlLineInfo;
992                         return li != null && li.HasLineInfo () ?
993                                 String.Format (" {0} (line {1}, column {2})", BaseURI, li.LineNumber, li.LinePosition) : String.Empty;
994                 }
995
996                 [MonoTODO]
997                 public virtual object ReadElementContentAsObject ()
998                 {
999                         return ReadElementContentAs (ValueType, null);
1000                 }
1001
1002                 [MonoTODO]
1003                 public virtual object ReadElementContentAsObject (string localName, string namespaceURI)
1004                 {
1005                         return ReadElementContentAs (ValueType, null, localName, namespaceURI);
1006                 }
1007
1008                 [MonoTODO]
1009                 public virtual object ReadContentAsObject ()
1010                 {
1011                         return ReadContentAs (ValueType, null);
1012                 }
1013
1014 #if NET_4_5
1015                 public virtual DateTimeOffset ReadContentAsDateTimeOffset ()
1016                 {
1017                         return XmlConvert.ToDateTimeOffset (ReadContentString ());
1018                 }
1019 #endif
1020
1021                 public virtual object ReadElementContentAs (Type returnType, IXmlNamespaceResolver namespaceResolver)
1022                 {
1023                         bool isEmpty = IsEmptyElement;
1024                         ReadStartElement ();
1025                         object obj = ValueAs (isEmpty ? String.Empty : ReadContentString (false), returnType, namespaceResolver, false);
1026                         if (!isEmpty)
1027                                 ReadEndElement ();
1028                         return obj;
1029                 }
1030
1031                 public virtual object ReadElementContentAs (Type returnType, IXmlNamespaceResolver namespaceResolver, string localName, string namespaceURI)
1032                 {
1033                         bool isEmpty = IsEmptyElement;
1034                         ReadStartElement (localName, namespaceURI);
1035                         if (isEmpty)
1036                                 return ValueAs (String.Empty, returnType, namespaceResolver, false);
1037                         object obj = ReadContentAs (returnType, namespaceResolver);
1038                         ReadEndElement ();
1039                         return obj;
1040                 }
1041
1042                 public virtual object ReadContentAs (Type returnType, IXmlNamespaceResolver namespaceResolver)
1043                 {
1044                         return ValueAs (ReadContentString (), returnType, namespaceResolver, false);
1045                 }
1046
1047                 private object ValueAs (string text, Type type, IXmlNamespaceResolver resolver, bool isArrayItem)
1048                 {
1049                         try {
1050                                 if (type == typeof (object))
1051                                         return text;
1052                                 if (type.IsArray && !isArrayItem) {
1053                                         var elemType = type.GetElementType ();
1054                                         var sarr = text.Split ((string []) null, StringSplitOptions.RemoveEmptyEntries);
1055                                         var ret = Array.CreateInstance (elemType, sarr.Length);
1056                                         for (int i = 0; i < ret.Length; i++)
1057                                                 ret.SetValue (ValueAs (sarr [i], elemType, resolver, true), i);
1058                                         return ret;
1059                                 }
1060
1061                                 if (type == typeof (XmlQualifiedName)) {
1062                                         if (resolver != null)
1063                                                 return XmlQualifiedName.Parse (text, resolver, true);
1064                                         else
1065                                                 return XmlQualifiedName.Parse (text, this, true);
1066                                 }
1067                                 if (type == typeof (Uri))
1068                                         return XmlConvert.ToUri (text);
1069                                 if (type == typeof (TimeSpan))
1070                                         return XmlConvert.ToTimeSpan (text);
1071                                 if (type == typeof (DateTimeOffset))
1072                                         return XmlConvert.ToDateTimeOffset (text);
1073
1074                                 switch (Type.GetTypeCode (type)) {
1075                                 case TypeCode.Boolean:
1076                                         return XQueryConvert.StringToBoolean (text);
1077                                 case TypeCode.DateTime:
1078                                         return XQueryConvert.StringToDateTime (text);
1079                                 case TypeCode.Decimal:
1080                                         return XQueryConvert.StringToDecimal (text);
1081                                 case TypeCode.Double:
1082                                         return XQueryConvert.StringToDouble (text);
1083                                 case TypeCode.Int32:
1084                                         return XQueryConvert.StringToInt (text);
1085                                 case TypeCode.Int64:
1086                                         return XQueryConvert.StringToInteger (text);
1087                                 case TypeCode.Single:
1088                                         return XQueryConvert.StringToFloat (text);
1089                                 case TypeCode.String:
1090                                         return text;
1091                                 }
1092                         } catch (Exception ex) {
1093                                 throw XmlError (String.Format ("Current text value '{0}' is not acceptable for specified type '{1}'. {2}", text, type, ex != null ? ex.Message : String.Empty), ex);
1094                         }
1095                         throw new ArgumentException (String.Format ("Specified type '{0}' is not supported.", type));
1096                 }
1097
1098                 public virtual bool ReadElementContentAsBoolean ()
1099                 {
1100                         try {
1101                                 return XQueryConvert.StringToBoolean (ReadElementContentAsString ());
1102                         } catch (FormatException ex) {
1103                                 throw XmlError ("Typed value is invalid.", ex);
1104                         }
1105                 }
1106
1107                 public virtual DateTime ReadElementContentAsDateTime ()
1108                 {
1109                         try {
1110                                 return XQueryConvert.StringToDateTime (ReadElementContentAsString ());
1111                         } catch (FormatException ex) {
1112                                 throw XmlError ("Typed value is invalid.", ex);
1113                         }
1114                 }
1115
1116                 public virtual decimal ReadElementContentAsDecimal ()
1117                 {
1118                         try {
1119                                 return XQueryConvert.StringToDecimal (ReadElementContentAsString ());
1120                         } catch (FormatException ex) {
1121                                 throw XmlError ("Typed value is invalid.", ex);
1122                         }
1123                 }
1124
1125                 public virtual double ReadElementContentAsDouble ()
1126                 {
1127                         try {
1128                                 return XQueryConvert.StringToDouble (ReadElementContentAsString ());
1129                         } catch (FormatException ex) {
1130                                 throw XmlError ("Typed value is invalid.", ex);
1131                         }
1132                 }
1133
1134                 public virtual float ReadElementContentAsFloat ()
1135                 {
1136                         try {
1137                                 return XQueryConvert.StringToFloat (ReadElementContentAsString ());
1138                         } catch (FormatException ex) {
1139                                 throw XmlError ("Typed value is invalid.", ex);
1140                         }
1141                 }
1142
1143                 public virtual int ReadElementContentAsInt ()
1144                 {
1145                         try {
1146                                 return XQueryConvert.StringToInt (ReadElementContentAsString ());
1147                         } catch (FormatException ex) {
1148                                 throw XmlError ("Typed value is invalid.", ex);
1149                         }
1150                 }
1151
1152                 public virtual long ReadElementContentAsLong ()
1153                 {
1154                         try {
1155                                 return XQueryConvert.StringToInteger (ReadElementContentAsString ());
1156                         } catch (FormatException ex) {
1157                                 throw XmlError ("Typed value is invalid.", ex);
1158                         }
1159                 }
1160
1161                 public virtual string ReadElementContentAsString ()
1162                 {
1163                         bool isEmpty = IsEmptyElement;
1164                         // unlike ReadStartElement() it rejects non-content nodes (this check is done before MoveToContent())
1165                         if (NodeType != XmlNodeType.Element)
1166                                 throw new InvalidOperationException (String.Format ("'{0}' is an element node.", NodeType));
1167                         ReadStartElement ();
1168                         if (isEmpty)
1169                                 return String.Empty;
1170                         string s = ReadContentString (false);
1171                         ReadEndElement ();
1172                         return s;
1173                 }
1174
1175                 public virtual bool ReadElementContentAsBoolean (string localName, string namespaceURI)
1176                 {
1177                         try {
1178                                 return XQueryConvert.StringToBoolean (ReadElementContentAsString (localName, namespaceURI));
1179                         } catch (FormatException ex) {
1180                                 throw XmlError ("Typed value is invalid.", ex);
1181                         }
1182                 }
1183
1184                 public virtual DateTime ReadElementContentAsDateTime (string localName, string namespaceURI)
1185                 {
1186                         try {
1187                                 return XQueryConvert.StringToDateTime (ReadElementContentAsString (localName, namespaceURI));
1188                         } catch (FormatException ex) {
1189                                 throw XmlError ("Typed value is invalid.", ex);
1190                         }
1191                 }
1192
1193                 public virtual decimal ReadElementContentAsDecimal (string localName, string namespaceURI)
1194                 {
1195                         try {
1196                                 return XQueryConvert.StringToDecimal (ReadElementContentAsString (localName, namespaceURI));
1197                         } catch (FormatException ex) {
1198                                 throw XmlError ("Typed value is invalid.", ex);
1199                         }
1200                 }
1201
1202                 public virtual double ReadElementContentAsDouble (string localName, string namespaceURI)
1203                 {
1204                         try {
1205                                 return XQueryConvert.StringToDouble (ReadElementContentAsString (localName, namespaceURI));
1206                         } catch (FormatException ex) {
1207                                 throw XmlError ("Typed value is invalid.", ex);
1208                         }
1209                 }
1210
1211                 public virtual float ReadElementContentAsFloat (string localName, string namespaceURI)
1212                 {
1213                         try {
1214                                 return XQueryConvert.StringToFloat (ReadElementContentAsString (localName, namespaceURI));
1215                         } catch (FormatException ex) {
1216                                 throw XmlError ("Typed value is invalid.", ex);
1217                         }
1218                 }
1219
1220                 public virtual int ReadElementContentAsInt (string localName, string namespaceURI)
1221                 {
1222                         try {
1223                                 return XQueryConvert.StringToInt (ReadElementContentAsString (localName, namespaceURI));
1224                         } catch (FormatException ex) {
1225                                 throw XmlError ("Typed value is invalid.", ex);
1226                         }
1227                 }
1228
1229                 public virtual long ReadElementContentAsLong (string localName, string namespaceURI)
1230                 {
1231                         try {
1232                                 return XQueryConvert.StringToInteger (ReadElementContentAsString (localName, namespaceURI));
1233                         } catch (FormatException ex) {
1234                                 throw XmlError ("Typed value is invalid.", ex);
1235                         }
1236                 }
1237
1238                 public virtual string ReadElementContentAsString (string localName, string namespaceURI)
1239                 {
1240                         bool isEmpty = IsEmptyElement;
1241                         // unlike ReadStartElement() it rejects non-content nodes (this check is done before MoveToContent())
1242                         if (NodeType != XmlNodeType.Element)
1243                                 throw new InvalidOperationException (String.Format ("'{0}' is an element node.", NodeType));
1244                         ReadStartElement (localName, namespaceURI);
1245                         if (isEmpty)
1246                                 return String.Empty;
1247                         string s = ReadContentString (false);
1248                         ReadEndElement ();
1249                         return s;
1250                 }
1251
1252                 public virtual bool ReadContentAsBoolean ()
1253                 {
1254                         try {
1255                                 return XQueryConvert.StringToBoolean (ReadContentString ());
1256                         } catch (FormatException ex) {
1257                                 throw XmlError ("Typed value is invalid.", ex);
1258                         }
1259                 }
1260
1261                 public virtual DateTime ReadContentAsDateTime ()
1262                 {
1263                         try {
1264                                 return XQueryConvert.StringToDateTime (ReadContentString ());
1265                         } catch (FormatException ex) {
1266                                 throw XmlError ("Typed value is invalid.", ex);
1267                         }
1268                 }
1269
1270                 public virtual decimal ReadContentAsDecimal ()
1271                 {
1272                         try {
1273                                 return XQueryConvert.StringToDecimal (ReadContentString ());
1274                         } catch (FormatException ex) {
1275                                 throw XmlError ("Typed value is invalid.", ex);
1276                         }
1277                 }
1278
1279                 public virtual double ReadContentAsDouble ()
1280                 {
1281                         try {
1282                                 return XQueryConvert.StringToDouble (ReadContentString ());
1283                         } catch (FormatException ex) {
1284                                 throw XmlError ("Typed value is invalid.", ex);
1285                         }
1286                 }
1287
1288                 public virtual float ReadContentAsFloat ()
1289                 {
1290                         try {
1291                                 return XQueryConvert.StringToFloat (ReadContentString ());
1292                         } catch (FormatException ex) {
1293                                 throw XmlError ("Typed value is invalid.", ex);
1294                         }
1295                 }
1296
1297                 public virtual int ReadContentAsInt ()
1298                 {
1299                         try {
1300                                 return XQueryConvert.StringToInt (ReadContentString ());
1301                         } catch (FormatException ex) {
1302                                 throw XmlError ("Typed value is invalid.", ex);
1303                         }
1304                 }
1305
1306                 public virtual long ReadContentAsLong ()
1307                 {
1308                         try {
1309                                 return XQueryConvert.StringToInteger (ReadContentString ());
1310                         } catch (FormatException ex) {
1311                                 throw XmlError ("Typed value is invalid.", ex);
1312                         }
1313                 }
1314
1315                 public virtual string ReadContentAsString ()
1316                 {
1317                         return ReadContentString ();
1318                 }
1319
1320                 public virtual int ReadContentAsBase64 (
1321                         byte [] buffer, int index, int count)
1322                 {
1323                         CheckSupport ();
1324                         return binary.ReadContentAsBase64 (
1325                                 buffer, index, count);
1326                 }
1327
1328                 public virtual int ReadContentAsBinHex (
1329                         byte [] buffer, int index, int count)
1330                 {
1331                         CheckSupport ();
1332                         return binary.ReadContentAsBinHex (
1333                                 buffer, index, count);
1334                 }
1335
1336                 public virtual int ReadElementContentAsBase64 (
1337                         byte [] buffer, int index, int count)
1338                 {
1339                         CheckSupport ();
1340                         return binary.ReadElementContentAsBase64 (
1341                                 buffer, index, count);
1342                 }
1343
1344                 public virtual int ReadElementContentAsBinHex (
1345                         byte [] buffer, int index, int count)
1346                 {
1347                         CheckSupport ();
1348                         return binary.ReadElementContentAsBinHex (
1349                                 buffer, index, count);
1350                 }
1351
1352                 private void CheckSupport ()
1353                 {
1354                         // Default implementation expects both.
1355                         if (!CanReadBinaryContent || !CanReadValueChunk)
1356                                 throw new NotSupportedException ();
1357                         if (binary == null)
1358                                 binary = new XmlReaderBinarySupport (this);
1359                 }
1360                 
1361 #endif
1362
1363                 public virtual int ReadValueChunk (char [] buffer, int index, int count)
1364                 {
1365                         if (!CanReadValueChunk)
1366                                 throw new NotSupportedException ();
1367                         if (binary == null)
1368                                 binary = new XmlReaderBinarySupport (this);
1369                         return binary.ReadValueChunk (buffer, index, count);
1370                 }
1371
1372                 public abstract void ResolveEntity ();
1373
1374                 public virtual void Skip ()
1375                 {
1376                         if (ReadState != ReadState.Interactive)
1377                                 return;
1378
1379                         MoveToElement ();
1380                         if (NodeType != XmlNodeType.Element || IsEmptyElement) {
1381                                 Read ();
1382                                 return;
1383                         }
1384                                 
1385                         int depth = Depth;
1386                         while (Read () && depth < Depth)
1387                                 ;
1388                         if (NodeType == XmlNodeType.EndElement)
1389                                 Read ();
1390                 }
1391
1392                 private XmlException XmlError (string message)
1393                 {
1394                         return new XmlException (this as IXmlLineInfo, BaseURI, message);
1395                 }
1396 #if NET_2_0
1397                 private XmlException XmlError (string message, Exception innerException)
1398                 {
1399                         return new XmlException (this as IXmlLineInfo, BaseURI, message);
1400                 }
1401 #endif
1402                 #endregion
1403
1404 #if NET_4_5
1405                 #region .NET 4.5 Async Methods
1406
1407                 bool asyncRunning;
1408
1409                 void StartAsync ()
1410                 {
1411                         if (!settings.Async)
1412                                 throw new InvalidOperationException ("Set XmlReaderSettings.Async to true if you want to use Async Methods.");
1413                         lock (this) {
1414                                 if (asyncRunning)
1415                                         throw new InvalidOperationException ("An asynchronous operation is already in progress.");
1416                                 asyncRunning = true;
1417                         }
1418                 }
1419
1420                 public virtual Task<bool> ReadAsync ()
1421                 {
1422                         StartAsync ();
1423                         return Task.Run (() => {
1424                                 try {
1425                                         return Read ();
1426                                 } finally {
1427                                         asyncRunning = false;
1428                                 }
1429                         });
1430                 }
1431
1432                 public virtual Task<string> GetValueAsync ()
1433                 {
1434                         StartAsync ();
1435                         return Task.Run (() => {
1436                                 try {
1437                                         return Value;
1438                                 } finally {
1439                                         asyncRunning = false;
1440                                 }
1441                         });
1442                 }
1443
1444                 public virtual Task<string> ReadInnerXmlAsync ()
1445                 {
1446                         StartAsync ();
1447                         return Task.Run (() => {
1448                                 try {
1449                                         return ReadInnerXml ();
1450                                 } finally {
1451                                         asyncRunning = false;
1452                                 }
1453                         });
1454                 }
1455
1456                 public virtual Task<string> ReadOuterXmlAsync ()
1457                 {
1458                         StartAsync ();
1459                         return Task.Run (() => {
1460                                 try {
1461                                         return ReadOuterXml ();
1462                                 } finally {
1463                                         asyncRunning = false;
1464                                 }
1465                         });
1466                 }
1467
1468                 public virtual Task<string> ReadContentAsStringAsync ()
1469                 {
1470                         StartAsync ();
1471                         return Task.Run (() => {
1472                                 try {
1473                                         return ReadContentAsString ();
1474                                 } finally {
1475                                         asyncRunning = false;
1476                                 }
1477                         });
1478                 }
1479
1480                 public virtual Task<int> ReadContentAsBase64Async (byte[] buffer, int index, int count)
1481                 {
1482                         StartAsync ();
1483                         return Task.Run (() => {
1484                                 try {
1485                                         return ReadContentAsBase64 (buffer, index, count);
1486                                 } finally {
1487                                         asyncRunning = false;
1488                                 }
1489                         });
1490                 }
1491
1492                 public virtual Task<int> ReadContentAsBinHexAsync (byte[] buffer, int index, int count)
1493                 {
1494                         StartAsync ();
1495                         return Task.Run (() => {
1496                                 try {
1497                                         return ReadContentAsBinHex (buffer, index, count);
1498                                 } finally {
1499                                         asyncRunning = false;
1500                                 }
1501                         });
1502                 }
1503
1504                 public virtual Task<int> ReadElementContentAsBase64Async (byte[] buffer, int index, int count)
1505                 {
1506                         StartAsync ();
1507                         return Task.Run (() => {
1508                                 try {
1509                                         return ReadElementContentAsBase64 (buffer, index, count);
1510                                 } finally {
1511                                         asyncRunning = false;
1512                                 }
1513                         });
1514                 }
1515
1516                 public virtual Task<int> ReadElementContentAsBinHexAsync (byte[] buffer, int index, int count)
1517                 {
1518                         StartAsync ();
1519                         return Task.Run (() => {
1520                                 try {
1521                                         return ReadElementContentAsBinHex (buffer, index, count);
1522                                 } finally {
1523                                         asyncRunning = false;
1524                                 }
1525                         });
1526                 }
1527
1528                 public virtual Task<int> ReadValueChunkAsync (char[] buffer, int index, int count)
1529                 {
1530                         StartAsync ();
1531                         return Task.Run (() => {
1532                                 try {
1533                                         return ReadValueChunk (buffer, index, count);
1534                                 } finally {
1535                                         asyncRunning = false;
1536                                 }
1537                         });
1538                 }
1539
1540                 public virtual Task<object> ReadContentAsAsync (Type returnType, IXmlNamespaceResolver namespaceResolver)
1541                 {
1542                         StartAsync ();
1543                         return Task.Run (() => {
1544                                 try {
1545                                         return ReadContentAs (returnType, namespaceResolver);
1546                                 } finally {
1547                                         asyncRunning = false;
1548                                 }
1549                         });
1550                 }
1551
1552                 public virtual Task<object> ReadContentAsObjectAsync ()
1553                 {
1554                         StartAsync ();
1555                         return Task.Run (() => {
1556                                 try {
1557                                         return ReadContentAsObject ();
1558                                 } finally {
1559                                         asyncRunning = false;
1560                                 }
1561                         });
1562                 }
1563
1564                 public virtual Task<object> ReadElementContentAsAsync (Type returnType, IXmlNamespaceResolver namespaceResolver)
1565                 {
1566                         StartAsync ();
1567                         return Task.Run (() => {
1568                                 try {
1569                                         return ReadElementContentAs (returnType, namespaceResolver);
1570                                 } finally {
1571                                         asyncRunning = false;
1572                                 }
1573                         });
1574                 }
1575
1576                 public virtual Task<object> ReadElementContentAsObjectAsync ()
1577                 {
1578                         StartAsync ();
1579                         return Task.Run (() => {
1580                                 try {
1581                                         return ReadElementContentAsObject ();
1582                                 } finally {
1583                                         asyncRunning = false;
1584                                 }
1585                         });
1586                 }
1587
1588                 public virtual Task<string> ReadElementContentAsStringAsync ()
1589                 {
1590                         StartAsync ();
1591                         return Task.Run (() => {
1592                                 try {
1593                                         return ReadElementContentAsString ();
1594                                 } finally {
1595                                         asyncRunning = false;
1596                                 }
1597                         });
1598                 }
1599
1600                 public virtual Task<XmlNodeType> MoveToContentAsync ()
1601                 {
1602                         StartAsync ();
1603                         return Task.Run (() => {
1604                                 try {
1605                                         return MoveToContent ();
1606                                 } finally {
1607                                         asyncRunning = false;
1608                                 }
1609                         });
1610                 }
1611
1612                 public virtual Task SkipAsync ()
1613                 {
1614                         StartAsync ();
1615                         return Task.Run (() => {
1616                                 try {
1617                                         Skip ();
1618                                 } finally {
1619                                         asyncRunning = false;
1620                                 }
1621                         });
1622                 }
1623
1624                 #endregion
1625 #endif
1626         }
1627 }