2008-09-17 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.XML / System.Xml / XmlReader.cs
index 1fc3dbea6b35509d1a688d689e4ab13120b518b6..4beecdc4e6b67c9af6ee0412e73494ae0a43af8e 100644 (file)
@@ -35,10 +35,12 @@ using System.Collections;
 using System.Diagnostics;
 using System.IO;
 using System.Text;
+#if !NET_2_1
 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
+#endif
+using Mono.Xml; // only required for NET_2_0
 
 namespace System.Xml
 {
@@ -121,7 +123,9 @@ namespace System.Xml
                        get { return AttributeCount > 0; }
                }
 
+#if !NET_2_1
                public abstract bool HasValue { get; }
+#endif
 
                public abstract bool IsEmptyElement { get; }
 
@@ -184,9 +188,11 @@ namespace System.Xml
                public abstract ReadState ReadState { get; }
 
 #if NET_2_0
+#if !NET_2_1
                public virtual IXmlSchemaInfo SchemaInfo {
                        get { return null; }
                }
+#endif
 
                public virtual XmlReaderSettings Settings {
                        get { return settings; }
@@ -231,8 +237,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 (
@@ -308,12 +320,17 @@ namespace System.Xml
                public static XmlReader Create (string url, XmlReaderSettings settings, XmlParserContext context)
                {
                        settings = PopulateSettings (settings);
-                       if (context == null)
-                               context = PopulateParserContext (settings, url);
-                       XmlTextReader xtr = new XmlTextReader (true, url, GetNodeType (settings), context);
-                       XmlReader ret = CreateCustomizedTextReader (xtr, settings);
-                       xtr.CloseInput = true;
-                       return xtr;
+                       bool closeInputBak = settings.CloseInput;
+                       try {
+                               settings.CloseInput = true; // forced. See XmlReaderCommonTests.CreateFromUrlClose().
+                               if (context == null)
+                                       context = PopulateParserContext (settings, url);
+                               XmlTextReader xtr = new XmlTextReader (false, settings.XmlResolver, url, GetNodeType (settings), context);
+                               XmlReader ret = CreateCustomizedTextReader (xtr, settings);
+                               return ret;
+                       } finally {
+                               settings.CloseInput = closeInputBak;
+                       }
                }
 
                public static XmlReader Create (Stream stream, XmlReaderSettings settings, XmlParserContext context)
@@ -337,6 +354,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 +404,9 @@ namespace System.Xml
 
                        reader = CreateValidatingXmlReader (reader, settings);
 
-                       if (reader.Settings != null ||
-                               settings.IgnoreComments ||
-                               settings.IgnoreProcessingInstructions ||
-                               settings.IgnoreWhitespace)
+                       if ( settings.IgnoreComments ||
+                            settings.IgnoreProcessingInstructions ||
+                            settings.IgnoreWhitespace)
                                return new XmlFilterReader (reader, settings);
                        else {
                                reader.settings = settings;
@@ -399,6 +416,9 @@ namespace System.Xml
 
                private static XmlReader CreateValidatingXmlReader (XmlReader reader, XmlReaderSettings settings)
                {
+#if NET_2_1
+                       return reader;
+#else
                        XmlValidatingReader xvr = null;
                        switch (settings.ValidationType) {
                        // Auto and XDR are obsoleted in 2.0 and therefore ignored.
@@ -424,10 +444,9 @@ namespace System.Xml
                        //      throw new NotImplementedException ();
 
                        return xvr != null ? xvr : reader;
-               }
 #endif
+               }
 
-#if NET_2_0
                void IDisposable.Dispose ()
                {
                        Dispose (false);
@@ -487,7 +506,7 @@ namespace System.Xml
                        if (i >= AttributeCount)
                                throw new ArgumentOutOfRangeException ();
                        MoveToFirstAttribute ();
-                       for (int a = 1; a < i; a++)
+                       for (int a = 0; a < i; a++)
                                MoveToNextAttribute ();
                }
 #else
@@ -544,7 +563,9 @@ namespace System.Xml
 
                public abstract bool Read ();
 
+#if !NET_2_1
                public abstract bool ReadAttributeValue ();
+#endif
 
                public virtual string ReadElementString ()
                {
@@ -838,7 +859,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 && name == Name)
                                        return true;
                        return false;
@@ -849,7 +871,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,6 +880,8 @@ namespace System.Xml
 
                public virtual XmlReader ReadSubtree ()
                {
+                       if (NodeType != XmlNodeType.Element)
+                               throw new InvalidOperationException ("ReadSubtree() can be invoked only when the reader is positioned on an element");
                        return new SubtreeXmlReader (this);
                }
 
@@ -1124,8 +1149,9 @@ namespace System.Xml
 
                public virtual string ReadElementContentAsString (string localName, string namespaceURI)
                {
+                       bool isEmpty = IsEmptyElement;
                        ReadStartElement (localName, namespaceURI);
-                       if (IsEmptyElement)
+                       if (isEmpty)
                                return String.Empty;
                        string s = ReadContentString (false);
                        ReadEndElement ();
@@ -1231,6 +1257,16 @@ namespace System.Xml
                        return binary.ReadElementContentAsBinHex (
                                buffer, offset, length);
                }
+
+               private void CheckSupport ()
+               {
+                       // Default implementation expects both.
+                       if (!CanReadBinaryContent || !CanReadValueChunk)
+                               throw new NotSupportedException ();
+                       if (binary == null)
+                               binary = new XmlReaderBinarySupport (this);
+               }
+               
 #endif
 
 #if NET_2_0
@@ -1248,15 +1284,6 @@ namespace System.Xml
                        return binary.ReadValueChunk (buffer, offset, length);
                }
 
-               private void CheckSupport ()
-               {
-                       // Default implementation expects both.
-                       if (!CanReadBinaryContent || !CanReadValueChunk)
-                               throw new NotSupportedException ();
-                       if (binary == null)
-                               binary = new XmlReaderBinarySupport (this);
-               }
-
                public abstract void ResolveEntity ();
 
                public virtual void Skip ()
@@ -1281,12 +1308,12 @@ 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
        }
 }