Merge pull request #950 from ermshiperete/bug-xamarin-2787
[mono.git] / mcs / class / System.Xml.Linq / System.Xml.Linq / XNodeReader.cs
index af47b10c912b92aabe55c70ee54d1ab41dfa621f..95631f1bbaaf3121ebc4a6a6d5017a36eba59125 100644 (file)
@@ -3,6 +3,7 @@
 //   Atsushi Enomoto
 //
 // Copyright 2007 Novell (http://www.novell.com)
+// Copyright 2011 Xamarin Inc (http://www.xamarin.com).
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -31,7 +32,7 @@ using XPI = System.Xml.Linq.XProcessingInstruction;
 
 namespace System.Xml.Linq
 {
-       internal class XNodeReader : XmlReader
+       internal class XNodeReader : XmlReader, IXmlLineInfo
        {
                ReadState state = ReadState.Initial;
                XNode node, start;
@@ -45,7 +46,29 @@ namespace System.Xml.Linq
                        this.node = node;
                        start = node;
                }
+               
+#if NET_4_0
+               internal bool OmitDuplicateNamespaces { get; set; }
+#endif
 
+               int IXmlLineInfo.LineNumber {
+                       get {
+                               var o = (XObject) GetCurrentAttribute () ?? node;
+                               return o != null ? o.LineNumber : 0;
+                       }
+               }
+               int IXmlLineInfo.LinePosition {
+                       get {
+                               var o = (XObject) GetCurrentAttribute () ?? node;
+                               return o != null ? o.LinePosition : 0;
+                       }
+               }
+               bool IXmlLineInfo.HasLineInfo ()
+               {
+                               var o = (XObject) GetCurrentAttribute () ?? node;
+                               return o != null ? ((IXmlLineInfo) o).HasLineInfo () : false;
+               }
+       
                public override int AttributeCount {
                        get {
                                if (state != ReadState.Interactive || end_element)
@@ -80,6 +103,8 @@ namespace System.Xml.Linq
 
                public override int Depth {
                        get {
+                               if (EOF)
+                                       return 0;
                                int i = 0;
                                // document.Depth = 0, root.Depth = 0, others.Depth = they depend
                                for (XNode n = node.Parent; n != null; n = n.Parent)
@@ -98,7 +123,7 @@ namespace System.Xml.Linq
 
                public override bool HasAttributes {
                        get {
-                               if (end_element || node == null)
+                               if (EOF || end_element || node == null)
                                        return false;
 
                                if (node is XElement)
@@ -109,6 +134,8 @@ namespace System.Xml.Linq
 
                public override bool HasValue {
                        get {
+                               if (EOF)
+                                       return false;
                                if (attr >= 0)
                                        return true;
                                switch (node.NodeType) {
@@ -123,16 +150,18 @@ namespace System.Xml.Linq
                }
 
                public override bool IsEmptyElement {
-                       get { return node is XElement ? ((XElement) node).IsEmpty : false; }
+                       get { return !EOF && attr < 0 && node is XElement ? ((XElement) node).IsEmpty : false; }
                }
 
-               XAttribute GetCurrentAttribute ()
+               internal XAttribute GetCurrentAttribute ()
                {
                        return GetXAttribute (attr);
                }
 
                XAttribute GetXAttribute (int idx)
                {
+                       if (EOF)
+                               return null;
                        XElement el = node as XElement;
                        if (el == null)
                                return null;
@@ -146,7 +175,7 @@ namespace System.Xml.Linq
                // XName for element and attribute, string for xmldecl attributes, doctype attribute, doctype name and PI, null for empty.
                object GetCurrentName ()
                {
-                       if (attr_value)
+                       if (EOF || attr_value)
                                return null;
                        return GetName (attr);
                }
@@ -233,7 +262,7 @@ namespace System.Xml.Linq
                                XElement el = (node as XElement) ?? node.Parent;
                                if (el == null)
                                        return String.Empty;
-                               return el.GetPrefixOfNamespace (name.Namespace);
+                               return el.GetPrefixOfNamespace (name.Namespace) ?? String.Empty;
                        }
                }
 
@@ -293,10 +322,13 @@ namespace System.Xml.Linq
 
                public override string LookupNamespace (string prefix)
                {
+                       if (EOF)
+                               return null;
                        XElement el = (node as XElement) ?? node.Parent;
                        if (el == null)
-                               return String.Empty;
-                       return el.GetNamespaceOfPrefix (prefix).NamespaceName;
+                               return null;
+                       var xn = el.GetNamespaceOfPrefix (prefix);
+                       return xn != XNamespace.None ? xn.NamespaceName : null;
                }
 
                public override bool MoveToElement ()
@@ -492,7 +524,9 @@ namespace System.Xml.Linq
                        return true;
                }
 
-               public override bool ReadAttributeValue ()
+               public
+               override
+               bool ReadAttributeValue ()
                {
                        if (attr < 0 || attr_value)
                                return false;
@@ -504,5 +538,10 @@ namespace System.Xml.Linq
                {
                        throw new NotSupportedException ();
                }
+               
+               // Note that this does not return attribute node.
+               internal XNode CurrentNode {
+                       get { return node; }
+               }
        }
 }