Merge pull request #900 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mcs / class / System.XML / System.Xml / XmlReader.cs
index 8b0745d36d0371b7fcdd684bcd5372040ebf8738..bb8030264e0872e94f09e941af5669a43f702e91 100644 (file)
@@ -37,8 +37,12 @@ using System.IO;
 using System.Text;
 using System.Xml.Schema; // only required for NET_2_0 (SchemaInfo)
 using System.Xml.Serialization; // only required for NET_2_0 (SchemaInfo)
-using Mono.Xml; // only required for NET_2_0
 using Mono.Xml.Schema; // only required for NET_2_0
+using Mono.Xml; // only required for NET_2_0
+#if NET_4_5
+using System.Threading;
+using System.Threading.Tasks;
+#endif
 
 namespace System.Xml
 {
@@ -121,7 +125,26 @@ namespace System.Xml
                        get { return AttributeCount > 0; }
                }
 
+#if NET_4_0
+               public virtual bool HasValue {
+                       get {
+                               switch (NodeType) {
+                               case XmlNodeType.Attribute:
+                               case XmlNodeType.Comment:
+                               case XmlNodeType.ProcessingInstruction:
+                               case XmlNodeType.SignificantWhitespace:
+                               case XmlNodeType.CDATA:
+                               case XmlNodeType.Text:
+                               case XmlNodeType.Whitespace:
+                               case XmlNodeType.XmlDeclaration:
+                                       return true;
+                               }
+                               return false;
+                       }
+               }
+#else
                public abstract bool HasValue { get; }
+#endif
 
                public abstract bool IsEmptyElement { get; }
 
@@ -213,7 +236,15 @@ namespace System.Xml
 
                #region Methods
 
+#if NET_4_5
+               public virtual void Close ()
+               {
+                       if (asyncRunning)
+                               throw new InvalidOperationException ("An asynchronous operation is already in progress.");
+               }
+#else
                public abstract void Close ();
+#endif
 
 #if NET_2_0
                private static XmlNameTable PopulateNameTable (
@@ -231,8 +262,14 @@ namespace System.Xml
                        XmlNameTable nt = PopulateNameTable (settings);
                        return new XmlParserContext (nt,
                                new XmlNamespaceManager (nt),
+                               null,
+                               null,
+                               null,
+                               null,
                                baseUri,
-                               XmlSpace.None);
+                               null,
+                               XmlSpace.None,
+                               null);
                }
 
                private static XmlNodeType GetNodeType (
@@ -245,91 +282,116 @@ namespace System.Xml
                                XmlNodeType.Document;
                }
 
-               public static XmlReader Create (Stream stream)
+               public static XmlReader Create (Stream input)
                {
-                       return Create (stream, null);
+                       return Create (input, null);
                }
 
-               public static XmlReader Create (string url)
+               public static XmlReader Create (string inputUri)
                {
-                       return Create (url, null);
+                       return Create (inputUri, null);
                }
 
-               public static XmlReader Create (TextReader reader)
+               public static XmlReader Create (TextReader input)
                {
-                       return Create (reader, null);
+                       return Create (input, null);
                }
 
-               public static XmlReader Create (string url, XmlReaderSettings settings)
+               public static XmlReader Create (string inputUri, XmlReaderSettings settings)
                {
-                       return Create (url, settings, null);
+                       return Create (inputUri, settings, null);
                }
 
-               public static XmlReader Create (Stream stream, XmlReaderSettings settings)
+               public static XmlReader Create (Stream input, XmlReaderSettings settings)
                {
-                       return Create (stream, settings, String.Empty);
+                       return Create (input, settings, String.Empty);
                }
 
-               public static XmlReader Create (TextReader reader, XmlReaderSettings settings)
+               public static XmlReader Create (TextReader input, XmlReaderSettings settings)
                {
-                       return Create (reader, settings, String.Empty);
+                       return Create (input, settings, String.Empty);
                }
 
                static XmlReaderSettings PopulateSettings (XmlReaderSettings src)
                {
+                       XmlReaderSettings copy;
                        if (src == null)
-                               return new XmlReaderSettings ();
+                               copy = new XmlReaderSettings ();
                        else
-                               return src.Clone ();
+                               copy = src.Clone ();
+#if NET_4_5
+                       copy.SetReadOnly ();
+#endif
+                       return copy;
+               }
+
+               static XmlReaderSettings PopulateSettings (XmlReader reader, XmlReaderSettings src)
+               {
+                       XmlReaderSettings copy;
+                       if (src == null)
+                               copy = new XmlReaderSettings ();
+                       else
+                               copy = src.Clone ();
+#if NET_4_5
+                       if (reader.Settings != null)
+                               copy.Async = reader.Settings.Async;
+                       copy.SetReadOnly ();
+#endif
+                       return copy;
                }
 
-               public static XmlReader Create (Stream stream, XmlReaderSettings settings, string baseUri)
+               public static XmlReader Create (Stream input, XmlReaderSettings settings, string baseUri)
                {
                        settings = PopulateSettings (settings);
-                       return Create (stream, settings,
+                       return Create (input, settings,
                                PopulateParserContext (settings, baseUri));
                }
 
-               public static XmlReader Create (TextReader reader, XmlReaderSettings settings, string baseUri)
+               public static XmlReader Create (TextReader input, XmlReaderSettings settings, string baseUri)
                {
                        settings = PopulateSettings (settings);
-                       return Create (reader, settings,
+                       return Create (input, settings,
                                PopulateParserContext (settings, baseUri));
                }
 
                public static XmlReader Create (XmlReader reader, XmlReaderSettings settings)
                {
-                       settings = PopulateSettings (settings);
+                       settings = PopulateSettings (reader, settings);
                        XmlReader r = CreateFilteredXmlReader (reader, settings);
                        r.settings = settings;
                        return r;
                }
 
-               public static XmlReader Create (string url, XmlReaderSettings settings, XmlParserContext context)
+               public static XmlReader Create (string inputUri, XmlReaderSettings settings, XmlParserContext inputContext)
                {
                        settings = PopulateSettings (settings);
-                       if (context == null)
-                               context = PopulateParserContext (settings, url);
-                       XmlTextReader xtr = new XmlTextReader (false, settings.XmlResolver, url, GetNodeType (settings), context);
-                       XmlReader ret = CreateCustomizedTextReader (xtr, settings);
-                       xtr.CloseInput = true; // forced. See XmlReaderCommonTests.CreateFromUrlClose().
-                       return ret;
+                       bool closeInputBak = settings.CloseInput;
+                       try {
+                               settings.CloseInput = true; // forced. See XmlReaderCommonTests.CreateFromUrlClose().
+                               if (inputContext == null)
+                                       inputContext = PopulateParserContext (settings, inputUri);
+                               XmlTextReader xtr = new XmlTextReader (false, settings.XmlResolver, inputUri, GetNodeType (settings), inputContext);
+                               XmlReader ret = CreateCustomizedTextReader (xtr, settings);
+                               return ret;
+                       } finally {
+                               settings.CloseInput = closeInputBak;
+                       }
                }
 
-               public static XmlReader Create (Stream stream, XmlReaderSettings settings, XmlParserContext context)
+               public static XmlReader Create (Stream input, XmlReaderSettings settings, XmlParserContext inputContext)
                {
                        settings = PopulateSettings (settings);
-                       if (context == null)
-                               context = PopulateParserContext (settings, String.Empty);
-                       return CreateCustomizedTextReader (new XmlTextReader (stream, GetNodeType (settings), context), settings);
+                       if (inputContext == null)
+                               inputContext = PopulateParserContext (settings, String.Empty);
+                       return CreateCustomizedTextReader (new XmlTextReader (input, GetNodeType (settings), inputContext), settings);
                }
 
-               public static XmlReader Create (TextReader reader, XmlReaderSettings settings, XmlParserContext context)
+               public static XmlReader Create (TextReader input, XmlReaderSettings settings, XmlParserContext inputContext)
                {
                        settings = PopulateSettings (settings);
-                       if (context == null)
-                               context = PopulateParserContext (settings, String.Empty);
-                       return CreateCustomizedTextReader (new XmlTextReader (context.BaseURI, reader, GetNodeType (settings), context), settings);
+                       if (inputContext == null)
+                               inputContext = PopulateParserContext (settings, String.Empty);
+                       return CreateCustomizedTextReader (new XmlTextReader (inputContext.BaseURI, input, GetNodeType (settings), inputContext), settings);
                }
 
                private static XmlReader CreateCustomizedTextReader (XmlTextReader reader, XmlReaderSettings settings)
@@ -337,6 +399,7 @@ namespace System.Xml
                        reader.XmlResolver = settings.XmlResolver;
                        // Normalization is set true by default.
                        reader.Normalization = true;
+                       reader.EntityHandling = EntityHandling.ExpandEntities;
 
                        if (settings.ProhibitDtd)
                                reader.ProhibitDtd = true;
@@ -386,10 +449,9 @@ namespace System.Xml
 
                        reader = CreateValidatingXmlReader (reader, settings);
 
-                       if (reader.Settings != null &&
-                           (settings.IgnoreComments ||
+                       if ( settings.IgnoreComments ||
                             settings.IgnoreProcessingInstructions ||
-                            settings.IgnoreWhitespace))
+                            settings.IgnoreWhitespace)
                                return new XmlFilterReader (reader, settings);
                        else {
                                reader.settings = settings;
@@ -425,10 +487,12 @@ namespace System.Xml
 
                        return xvr != null ? xvr : reader;
                }
-#endif
 
-#if NET_2_0
-               void IDisposable.Dispose ()
+#if NET_4_0
+               public void Dispose ()
+#else
+               void IDisposable.Dispose() 
+#endif
                {
                        Dispose (false);
                }
@@ -444,18 +508,16 @@ namespace System.Xml
 
                public abstract string GetAttribute (string name);
 
-               public abstract string GetAttribute (
-                       string localName,
-                       string namespaceName);
+               public abstract string GetAttribute (string name, string namespaceURI);
 
-               public static bool IsName (string s)
+               public static bool IsName (string str)
                {
-                       return s != null && XmlChar.IsName (s);
+                       return str != null && XmlChar.IsName (str);
                }
 
-               public static bool IsNameToken (string s)
+               public static bool IsNameToken (string str)
                {
-                       return s != null && XmlChar.IsNmToken (s);
+                       return str != null && XmlChar.IsNmToken (str);
                }
 
                public virtual bool IsStartElement ()
@@ -471,12 +533,12 @@ namespace System.Xml
                        return (Name == name);
                }
 
-               public virtual bool IsStartElement (string localName, string namespaceName)
+               public virtual bool IsStartElement (string localname, string ns)
                {
                        if (!IsStartElement ())
                                return false;
 
-                       return (LocalName == localName && NamespaceURI == namespaceName);
+                       return (LocalName == localname && NamespaceURI == ns);
                }
 
                public abstract string LookupNamespace (string prefix);
@@ -496,9 +558,7 @@ namespace System.Xml
 
                public abstract bool MoveToAttribute (string name);
 
-               public abstract bool MoveToAttribute (
-                       string localName,
-                       string namespaceName);
+               public abstract bool MoveToAttribute (string name, string ns);
 
                private bool IsContent (XmlNodeType nodeType)
                {
@@ -525,6 +585,14 @@ namespace System.Xml
 
                public virtual XmlNodeType MoveToContent ()
                {
+                       switch (ReadState) {
+                       case ReadState.Initial:
+                       case ReadState.Interactive:
+                               break;
+                       default:
+                               return NodeType;
+                       }
+
                        if (NodeType == XmlNodeType.Attribute)
                                MoveToElement ();
 
@@ -598,7 +666,7 @@ namespace System.Xml
                        return result;
                }
 
-               public virtual string ReadElementString (string localName, string namespaceName)
+               public virtual string ReadElementString (string localname, string ns)
                {
                        if (MoveToContent () != XmlNodeType.Element) {
                                string error = String.Format ("'{0}' is an invalid node type.",
@@ -606,7 +674,7 @@ namespace System.Xml
                                throw XmlError (error);
                        }
 
-                       if (localName != LocalName || NamespaceURI != namespaceName) {
+                       if (localname != LocalName || NamespaceURI != ns) {
                                string error = String.Format ("The {0} tag from namespace {1} is expected.",
                                                              LocalName, NamespaceURI);
                                throw XmlError (error);
@@ -712,7 +780,7 @@ namespace System.Xml
                        Read ();
                }
 
-               public virtual void ReadStartElement (string localName, string namespaceName)
+               public virtual void ReadStartElement (string localname, string ns)
                {
                        if (MoveToContent () != XmlNodeType.Element) {
                                string error = String.Format ("'{0}' is an invalid node type.",
@@ -720,9 +788,9 @@ namespace System.Xml
                                throw XmlError (error);
                        }
 
-                       if (localName != LocalName || NamespaceURI != namespaceName) {
+                       if (localname != LocalName || NamespaceURI != ns) {
                                string error = String.Format ("Expecting {0} tag from namespace {1}, got {2} and {3} instead",
-                                                             localName, namespaceName,
+                                                             localname, ns,
                                                              LocalName, NamespaceURI);
                                throw XmlError (error);
                        }
@@ -828,7 +896,7 @@ namespace System.Xml
                public virtual bool ReadToFollowing (string localName, string namespaceURI)
                {
                        while (Read ())
-                               if (NodeType == XmlNodeType.Element && localName == Name && namespaceURI == NamespaceURI)
+                               if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
                                        return true;
                        return false;
                }
@@ -837,8 +905,10 @@ namespace System.Xml
                {
                        if (ReadState != ReadState.Interactive)
                                return false;
+                       MoveToElement ();
                        int depth = Depth;
-                       for (Skip (); depth >= Depth; Skip ())
+                       Skip ();
+                       for (; !EOF && depth <= Depth; Skip ())
                                if (NodeType == XmlNodeType.Element && name == Name)
                                        return true;
                        return false;
@@ -849,7 +919,8 @@ namespace System.Xml
                        if (ReadState != ReadState.Interactive)
                                return false;
                        int depth = Depth;
-                       for (Skip (); depth >= Depth; Skip ())
+                       Skip ();
+                       for (; !EOF && depth <= Depth; Skip ())
                                if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
                                        return true;
                        return false;
@@ -857,12 +928,16 @@ namespace System.Xml
 
                public virtual XmlReader ReadSubtree ()
                {
+                       if (NodeType != XmlNodeType.Element)
+                               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 ()));
                        return new SubtreeXmlReader (this);
                }
 
                private string ReadContentString ()
                {
-                       if (NodeType == XmlNodeType.Attribute)
+                       // The latter condition indicates that this XmlReader is on an attribute value
+                       // (HasAttributes is to indicate it is on attribute value).
+                       if (NodeType == XmlNodeType.Attribute || NodeType != XmlNodeType.Element && HasAttributes)
                                return Value;
                        return ReadContentString (true);
                }
@@ -876,8 +951,10 @@ namespace System.Xml
                                case XmlNodeType.Whitespace:
                                case XmlNodeType.CDATA:
                                        break;
-                               default:
+                               case XmlNodeType.Element:
                                        throw new InvalidOperationException (String.Format ("Node type {0} is not supported in this operation.{1}", NodeType, GetLocation ()));
+                               default:
+                                       return String.Empty;
                                }
                        }
 
@@ -926,54 +1003,100 @@ namespace System.Xml
                        return ReadContentAs (ValueType, null);
                }
 
-               public virtual object ReadElementContentAs (Type type, IXmlNamespaceResolver resolver)
+#if NET_4_5
+               public virtual DateTimeOffset ReadContentAsDateTimeOffset ()
+               {
+                       try {
+                               return XmlConvert.ToDateTimeOffset (ReadContentString ());
+                       } catch (Exception e) {
+                               throw XmlError ("Typed value is invalid.", e);
+                       }
+               }
+#endif
+
+               public virtual object ReadElementContentAs (Type returnType, IXmlNamespaceResolver namespaceResolver)
                {
                        bool isEmpty = IsEmptyElement;
                        ReadStartElement ();
-                       object obj = ValueAs (isEmpty ? String.Empty : ReadContentString (false), type, resolver);
+                       object obj = ValueAs (isEmpty ? String.Empty : ReadContentString (false), returnType, namespaceResolver, false);
                        if (!isEmpty)
                                ReadEndElement ();
                        return obj;
                }
 
-               public virtual object ReadElementContentAs (Type type, IXmlNamespaceResolver resolver, string localName, string namespaceURI)
+               public virtual object ReadElementContentAs (Type returnType, IXmlNamespaceResolver namespaceResolver, string localName, string namespaceURI)
                {
+                       if (localName == null)
+                               throw new ArgumentNullException ("localName");
+                       if (namespaceURI == null)
+                               throw new ArgumentNullException ("namespaceURI");
+
+                       bool isEmpty = IsEmptyElement;
                        ReadStartElement (localName, namespaceURI);
-                       object obj = ReadContentAs (type, resolver);
+                       if (isEmpty)
+                               return ValueAs (String.Empty, returnType, namespaceResolver, false);
+                       object obj = ReadContentAs (returnType, namespaceResolver);
                        ReadEndElement ();
                        return obj;
                }
 
-               public virtual object ReadContentAs (Type type, IXmlNamespaceResolver resolver)
+               public virtual object ReadContentAs (Type returnType, IXmlNamespaceResolver namespaceResolver)
                {
-                       return ValueAs (ReadContentString (), type, resolver);
+                       return ValueAs (ReadContentString (), returnType, namespaceResolver, false);
                }
 
-               private object ValueAs (string text, Type type, IXmlNamespaceResolver resolver)
+               private object ValueAs (string text, Type type, IXmlNamespaceResolver resolver, bool isArrayItem)
                {
                        try {
                                if (type == typeof (object))
                                        return text;
+                               if (type.IsArray && !isArrayItem) {
+                                       var elemType = type.GetElementType ();
+                                       var sarr = text.Split ((string []) null, StringSplitOptions.RemoveEmptyEntries);
+                                       var ret = Array.CreateInstance (elemType, sarr.Length);
+                                       for (int i = 0; i < ret.Length; i++)
+                                               ret.SetValue (ValueAs (sarr [i], elemType, resolver, true), i);
+                                       return ret;
+                               }
+
                                if (type == typeof (XmlQualifiedName)) {
                                        if (resolver != null)
-                                               return XmlQualifiedName.Parse (text, resolver);
+                                               return XmlQualifiedName.Parse (text, resolver, true);
                                        else
-                                               return XmlQualifiedName.Parse (text, this);
+                                               return XmlQualifiedName.Parse (text, this, true);
                                }
+                               if (type == typeof (Uri))
+                                       return XmlConvert.ToUri (text);
+                               if (type == typeof (TimeSpan))
+                                       return XmlConvert.ToTimeSpan (text);
+                               if (type == typeof (DateTimeOffset))
+                                       return XmlConvert.ToDateTimeOffset (text);
 
                                switch (Type.GetTypeCode (type)) {
                                case TypeCode.Boolean:
                                        return XQueryConvert.StringToBoolean (text);
+                               case TypeCode.Byte:
+                                       return XmlConvert.ToByte (text);
+                               case TypeCode.SByte:
+                                       return XmlConvert.ToSByte (text);
+                               case TypeCode.Int16:
+                                       return XmlConvert.ToInt16 (text);
+                               case TypeCode.UInt16:
+                                       return XQueryConvert.StringToUnsignedShort (text);
+                               case TypeCode.Int32:
+                                       return XQueryConvert.StringToInt (text);
+                               case TypeCode.UInt32:
+                                       return XQueryConvert.StringToUnsignedInt (text);
+                               case TypeCode.Int64:
+                                       return XQueryConvert.StringToInteger (text);
+                               case TypeCode.UInt64:
+                                       return XQueryConvert.StringToUnsignedLong (text);
                                case TypeCode.DateTime:
                                        return XQueryConvert.StringToDateTime (text);
                                case TypeCode.Decimal:
                                        return XQueryConvert.StringToDecimal (text);
                                case TypeCode.Double:
                                        return XQueryConvert.StringToDouble (text);
-                               case TypeCode.Int32:
-                                       return XQueryConvert.StringToInt (text);
-                               case TypeCode.Int64:
-                                       return XQueryConvert.StringToInteger (text);
                                case TypeCode.Single:
                                        return XQueryConvert.StringToFloat (text);
                                case TypeCode.String:
@@ -982,7 +1105,7 @@ namespace System.Xml
                        } catch (Exception ex) {
                                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);
                        }
-                       throw new ArgumentException (String.Format ("Specified type '{0}' is not supported.", type));
+                       throw new XmlException (String.Format ("Specified type '{0}' is not supported.", type));
                }
 
                public virtual bool ReadElementContentAsBoolean ()
@@ -1051,6 +1174,9 @@ namespace System.Xml
                public virtual string ReadElementContentAsString ()
                {
                        bool isEmpty = IsEmptyElement;
+                       // unlike ReadStartElement() it rejects non-content nodes (this check is done before MoveToContent())
+                       if (NodeType != XmlNodeType.Element)
+                               throw new InvalidOperationException (String.Format ("'{0}' is an element node.", NodeType));
                        ReadStartElement ();
                        if (isEmpty)
                                return String.Empty;
@@ -1124,8 +1250,12 @@ namespace System.Xml
 
                public virtual string ReadElementContentAsString (string localName, string namespaceURI)
                {
+                       bool isEmpty = IsEmptyElement;
+                       // unlike ReadStartElement() it rejects non-content nodes (this check is done before MoveToContent())
+                       if (NodeType != XmlNodeType.Element)
+                               throw new InvalidOperationException (String.Format ("'{0}' is an element node.", NodeType));
                        ReadStartElement (localName, namespaceURI);
-                       if (IsEmptyElement)
+                       if (isEmpty)
                                return String.Empty;
                        string s = ReadContentString (false);
                        ReadEndElement ();
@@ -1201,60 +1331,55 @@ namespace System.Xml
                }
 
                public virtual int ReadContentAsBase64 (
-                       byte [] buffer, int offset, int length)
+                       byte [] buffer, int index, int count)
                {
                        CheckSupport ();
                        return binary.ReadContentAsBase64 (
-                               buffer, offset, length);
+                               buffer, index, count);
                }
 
                public virtual int ReadContentAsBinHex (
-                       byte [] buffer, int offset, int length)
+                       byte [] buffer, int index, int count)
                {
                        CheckSupport ();
                        return binary.ReadContentAsBinHex (
-                               buffer, offset, length);
+                               buffer, index, count);
                }
 
                public virtual int ReadElementContentAsBase64 (
-                       byte [] buffer, int offset, int length)
+                       byte [] buffer, int index, int count)
                {
                        CheckSupport ();
                        return binary.ReadElementContentAsBase64 (
-                               buffer, offset, length);
+                               buffer, index, count);
                }
 
                public virtual int ReadElementContentAsBinHex (
-                       byte [] buffer, int offset, int length)
+                       byte [] buffer, int index, int count)
                {
                        CheckSupport ();
                        return binary.ReadElementContentAsBinHex (
-                               buffer, offset, length);
+                               buffer, index, count);
                }
-#endif
 
-#if NET_2_0
-               public virtual int ReadValueChunk (
-                       char [] buffer, int offset, int length)
-#else
-               internal virtual int ReadValueChunk (
-                       char [] buffer, int offset, int length)
-#endif
+               private void CheckSupport ()
                {
-                       if (!CanReadValueChunk)
+                       // Default implementation expects both.
+                       if (!CanReadBinaryContent || !CanReadValueChunk)
                                throw new NotSupportedException ();
                        if (binary == null)
                                binary = new XmlReaderBinarySupport (this);
-                       return binary.ReadValueChunk (buffer, offset, length);
                }
+               
+#endif
 
-               private void CheckSupport ()
+               public virtual int ReadValueChunk (char [] buffer, int index, int count)
                {
-                       // Default implementation expects both.
-                       if (!CanReadBinaryContent || !CanReadValueChunk)
+                       if (!CanReadValueChunk)
                                throw new NotSupportedException ();
                        if (binary == null)
                                binary = new XmlReaderBinarySupport (this);
+                       return binary.ReadValueChunk (buffer, index, count);
                }
 
                public abstract void ResolveEntity ();
@@ -1281,12 +1406,235 @@ namespace System.Xml
                {
                        return new XmlException (this as IXmlLineInfo, BaseURI, message);
                }
-
+#if NET_2_0
                private XmlException XmlError (string message, Exception innerException)
                {
                        return new XmlException (this as IXmlLineInfo, BaseURI, message);
                }
+#endif
+               #endregion
+
+#if NET_4_5
+               #region .NET 4.5 Async Methods
+
+               bool asyncRunning;
+
+               void StartAsync ()
+               {
+                       if (!settings.Async)
+                               throw new InvalidOperationException ("Set XmlReaderSettings.Async to true if you want to use Async Methods.");
+                       lock (this) {
+                               if (asyncRunning)
+                                       throw new InvalidOperationException ("An asynchronous operation is already in progress.");
+                               asyncRunning = true;
+                       }
+               }
+
+               public virtual Task<bool> ReadAsync ()
+               {
+                       StartAsync ();
+                       return Task.Run (() => {
+                               try {
+                                       return Read ();
+                               } finally {
+                                       asyncRunning = false;
+                               }
+                       });
+               }
+
+               public virtual Task<string> GetValueAsync ()
+               {
+                       StartAsync ();
+                       return Task.Run (() => {
+                               try {
+                                       return Value;
+                               } finally {
+                                       asyncRunning = false;
+                               }
+                       });
+               }
+
+               public virtual Task<string> ReadInnerXmlAsync ()
+               {
+                       StartAsync ();
+                       return Task.Run (() => {
+                               try {
+                                       return ReadInnerXml ();
+                               } finally {
+                                       asyncRunning = false;
+                               }
+                       });
+               }
+
+               public virtual Task<string> ReadOuterXmlAsync ()
+               {
+                       StartAsync ();
+                       return Task.Run (() => {
+                               try {
+                                       return ReadOuterXml ();
+                               } finally {
+                                       asyncRunning = false;
+                               }
+                       });
+               }
+
+               public virtual Task<string> ReadContentAsStringAsync ()
+               {
+                       StartAsync ();
+                       return Task.Run (() => {
+                               try {
+                                       return ReadContentAsString ();
+                               } finally {
+                                       asyncRunning = false;
+                               }
+                       });
+               }
+
+               public virtual Task<int> ReadContentAsBase64Async (byte[] buffer, int index, int count)
+               {
+                       StartAsync ();
+                       return Task.Run (() => {
+                               try {
+                                       return ReadContentAsBase64 (buffer, index, count);
+                               } finally {
+                                       asyncRunning = false;
+                               }
+                       });
+               }
+
+               public virtual Task<int> ReadContentAsBinHexAsync (byte[] buffer, int index, int count)
+               {
+                       StartAsync ();
+                       return Task.Run (() => {
+                               try {
+                                       return ReadContentAsBinHex (buffer, index, count);
+                               } finally {
+                                       asyncRunning = false;
+                               }
+                       });
+               }
+
+               public virtual Task<int> ReadElementContentAsBase64Async (byte[] buffer, int index, int count)
+               {
+                       StartAsync ();
+                       return Task.Run (() => {
+                               try {
+                                       return ReadElementContentAsBase64 (buffer, index, count);
+                               } finally {
+                                       asyncRunning = false;
+                               }
+                       });
+               }
+
+               public virtual Task<int> ReadElementContentAsBinHexAsync (byte[] buffer, int index, int count)
+               {
+                       StartAsync ();
+                       return Task.Run (() => {
+                               try {
+                                       return ReadElementContentAsBinHex (buffer, index, count);
+                               } finally {
+                                       asyncRunning = false;
+                               }
+                       });
+               }
+
+               public virtual Task<int> ReadValueChunkAsync (char[] buffer, int index, int count)
+               {
+                       StartAsync ();
+                       return Task.Run (() => {
+                               try {
+                                       return ReadValueChunk (buffer, index, count);
+                               } finally {
+                                       asyncRunning = false;
+                               }
+                       });
+               }
+
+               public virtual Task<object> ReadContentAsAsync (Type returnType, IXmlNamespaceResolver namespaceResolver)
+               {
+                       StartAsync ();
+                       return Task.Run (() => {
+                               try {
+                                       return ReadContentAs (returnType, namespaceResolver);
+                               } finally {
+                                       asyncRunning = false;
+                               }
+                       });
+               }
+
+               public virtual Task<object> ReadContentAsObjectAsync ()
+               {
+                       StartAsync ();
+                       return Task.Run (() => {
+                               try {
+                                       return ReadContentAsObject ();
+                               } finally {
+                                       asyncRunning = false;
+                               }
+                       });
+               }
+
+               public virtual Task<object> ReadElementContentAsAsync (Type returnType, IXmlNamespaceResolver namespaceResolver)
+               {
+                       StartAsync ();
+                       return Task.Run (() => {
+                               try {
+                                       return ReadElementContentAs (returnType, namespaceResolver);
+                               } finally {
+                                       asyncRunning = false;
+                               }
+                       });
+               }
+
+               public virtual Task<object> ReadElementContentAsObjectAsync ()
+               {
+                       StartAsync ();
+                       return Task.Run (() => {
+                               try {
+                                       return ReadElementContentAsObject ();
+                               } finally {
+                                       asyncRunning = false;
+                               }
+                       });
+               }
+
+               public virtual Task<string> ReadElementContentAsStringAsync ()
+               {
+                       StartAsync ();
+                       return Task.Run (() => {
+                               try {
+                                       return ReadElementContentAsString ();
+                               } finally {
+                                       asyncRunning = false;
+                               }
+                       });
+               }
+
+               public virtual Task<XmlNodeType> MoveToContentAsync ()
+               {
+                       StartAsync ();
+                       return Task.Run (() => {
+                               try {
+                                       return MoveToContent ();
+                               } finally {
+                                       asyncRunning = false;
+                               }
+                       });
+               }
+
+               public virtual Task SkipAsync ()
+               {
+                       StartAsync ();
+                       return Task.Run (() => {
+                               try {
+                                       Skip ();
+                               } finally {
+                                       asyncRunning = false;
+                               }
+                       });
+               }
 
                #endregion
+#endif
        }
 }