2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / System.XML / Mono.Xml.XPath / XPathNavigatorReader.cs
index 9fb0015232463ab196d2d36fd71f60912379e0ce..5a5cf1f3f2c4169e32f64705b140f1a4e0a3d0d7 100755 (executable)
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
 //\r
+\r
 using System;\r
 using System.Text;\r
 using System.Xml;\r
+using System.Xml.Schema;\r
 using System.Xml.XPath;\r
 \r
 namespace Mono.Xml.XPath\r
@@ -39,6 +41,13 @@ namespace Mono.Xml.XPath
        {\r
                public XPathNavigatorReader (XPathNavigator nav)\r
                {\r
+                       // It seems that this class have only to support linked\r
+                       // node as its parameter\r
+                       switch (nav.NodeType) {\r
+                       case XPathNodeType.Attribute:\r
+                       case XPathNodeType.Namespace:\r
+                               throw new InvalidOperationException (String.Format ("NodeType {0} is not supported to read as a subtree of an XPathNavigator.", nav.NodeType));\r
+                       }\r
                        root = nav.Clone ();\r
                        current = nav.Clone ();\r
                }\r
@@ -50,7 +59,9 @@ namespace Mono.Xml.XPath
                bool endElement;\r
                bool attributeValueConsumed;\r
                StringBuilder readStringBuffer = new StringBuilder ();\r
+#if NET_2_0\r
                StringBuilder innerXmlBuilder = new StringBuilder ();\r
+#endif\r
 \r
                int depth = 0;\r
                int attributeCount = 0;\r
@@ -58,6 +69,17 @@ namespace Mono.Xml.XPath
                bool nextIsEOF;\r
 \r
                #region Properties\r
+\r
+#if NET_2_0\r
+               public override bool CanReadBinaryContent {\r
+                       get { return true; }\r
+               }\r
+\r
+               public override bool CanReadValueChunk {\r
+                       get { return true; }\r
+               }\r
+#endif\r
+\r
                public override XmlNodeType NodeType \r
                {\r
                        get {\r
@@ -65,16 +87,9 @@ namespace Mono.Xml.XPath
                                        return XmlNodeType.None;\r
                                if (endElement)\r
                                        return XmlNodeType.EndElement;\r
-                               if (attributeValueConsumed) {\r
-                                       switch (current.NodeType) {\r
-                                       case XPathNodeType.Whitespace:\r
-                                               return XmlNodeType.Whitespace;\r
-                                       case XPathNodeType.SignificantWhitespace:\r
-                                               return XmlNodeType.SignificantWhitespace;\r
-                                       default:\r
-                                               return XmlNodeType.Text;\r
-                                       }\r
-                               }\r
+                               if (attributeValueConsumed)\r
+                                       // Is there any way to get other kind of nodes than Text?\r
+                                       return XmlNodeType.Text;\r
 \r
                                switch (current.NodeType) {\r
                                case XPathNodeType.Namespace:\r
@@ -102,19 +117,47 @@ namespace Mono.Xml.XPath
                }\r
 \r
                public override string Name {\r
-                       get { return eof ? String.Empty : current.Name; }\r
+                       get {\r
+                               if (eof)\r
+                                       return String.Empty;\r
+                               else if (current.NodeType == XPathNodeType.Namespace)\r
+                                       return current.Name == String.Empty ? "xmlns" : "xmlns:" + current.Name;\r
+                               else\r
+                                       return current.Name;\r
+                       }\r
                }\r
 \r
                public override string LocalName {\r
-                       get { return eof ? String.Empty : current.LocalName; }\r
+                       get {\r
+                               if (eof)\r
+                                       return String.Empty;\r
+                               else if (current.NodeType == XPathNodeType.Namespace && current.LocalName == String.Empty)\r
+                                       return "xmlns";\r
+                               else\r
+                                       return current.LocalName;\r
+                       }\r
                }\r
 \r
                public override string NamespaceURI {\r
-                       get { return eof ? String.Empty : current.NamespaceURI; }\r
+                       get {\r
+                               if (eof)\r
+                                       return String.Empty;\r
+                               else if (current.NodeType == XPathNodeType.Namespace)\r
+                                       return "http://www.w3.org/2000/xmlns/";\r
+                               else\r
+                                       return current.NamespaceURI;\r
+                       }\r
                }\r
 \r
                public override string Prefix {\r
-                       get { return eof ? String.Empty : current.Prefix; }\r
+                       get {\r
+                               if (eof)\r
+                                       return String.Empty;\r
+                               else if (current.NodeType == XPathNodeType.Namespace && current.LocalName != String.Empty)\r
+                                       return "xmlns";\r
+                               else\r
+                                       return current.Prefix;\r
+                       }\r
                }\r
 \r
                public override bool HasValue {\r
@@ -173,9 +216,15 @@ namespace Mono.Xml.XPath
                        get { return current.IsEmptyElement; }\r
                }\r
 \r
-               // It makes no sense.\r
                public override bool IsDefault {\r
-                       get { return false; }\r
+                       get {\r
+#if NET_2_0\r
+                               IXmlSchemaInfo si = current as IXmlSchemaInfo;\r
+                               return si != null && si.IsDefault;\r
+#else\r
+                               return false; // no way to check this.\r
+#endif\r
+                       }\r
                }\r
 \r
                // It makes no sense.\r
@@ -183,6 +232,12 @@ namespace Mono.Xml.XPath
                        get { return '\"'; }\r
                }\r
 \r
+#if NET_2_0\r
+               public override IXmlSchemaInfo SchemaInfo {\r
+                       get { return current.SchemaInfo; }\r
+               }\r
+#endif\r
+\r
                public override string XmlLang {\r
                        get { return current.XmlLang; }\r
                }\r
@@ -214,36 +269,39 @@ namespace Mono.Xml.XPath
                        return count;\r
                }\r
                \r
-               private XPathNavigator GetAttributeNavigator (int i)\r
+               private bool MoveToAttributeNavigator (int i)\r
                {\r
-                       XPathNavigator backup = current.Clone ();\r
-                       try {\r
-                               switch (current.NodeType) {\r
-                               case XPathNodeType.Attribute:\r
-                                       this.MoveToElement ();\r
-                                       goto case XPathNodeType.Element;\r
-                               case XPathNodeType.Element:\r
-                                       if (MoveToFirstAttribute ())\r
-                                               if (i == 0)\r
-                                                       return current.Clone ();\r
-                                       for (int count = 1; this.MoveToNextAttribute (); count++)\r
-                                               if (count == i)\r
-                                                       return current.Clone ();\r
-                                       break;\r
+                       switch (current.NodeType) {\r
+                       case XPathNodeType.Namespace:\r
+                       case XPathNodeType.Attribute:\r
+                               this.MoveToElement ();\r
+                               goto case XPathNodeType.Element;\r
+                       case XPathNodeType.Element:\r
+                               int count = 0;\r
+                               if (MoveToFirstAttribute ()) {\r
+                                       if (i == 0)\r
+                                               return true;\r
                                }\r
-                               return null;\r
-                       } finally {\r
-                               current = backup;\r
+                               for (count++; this.MoveToNextAttribute (); count++) {\r
+                                       if (count == i)\r
+                                               return true;\r
+                               }\r
+                               break;\r
                        }\r
+                       return false;\r
                }\r
 \r
                public override string this [int i] {\r
                        get {\r
-                               XPathNavigator test = GetAttributeNavigator (i);\r
-                               if (test != null)\r
-                                       return test.Value;\r
-                               else\r
-                                       throw new ArgumentOutOfRangeException ();\r
+                               XPathNavigator backup = current.Clone ();\r
+                               try {\r
+                                       if (MoveToAttributeNavigator (i))\r
+                                               return Value;\r
+                                       else\r
+                                               throw new ArgumentOutOfRangeException ();\r
+                               } finally {\r
+                                       current.MoveTo (backup);\r
+                               }\r
                        }\r
                }\r
 \r
@@ -278,19 +336,17 @@ namespace Mono.Xml.XPath
                }\r
 \r
                public override bool EOF {\r
-                       get {\r
-                               return eof || ReadState == ReadState.EndOfFile;\r
-                       }\r
+                       get { return ReadState == ReadState.EndOfFile; }\r
                }\r
 \r
                public override ReadState ReadState {\r
                        get {\r
+                               if (eof)\r
+                                       return ReadState.EndOfFile;\r
                                if (closed)\r
                                        return ReadState.Closed;\r
                                else if (!started)\r
                                        return ReadState.Initial;\r
-                               else if (eof)\r
-                                       return ReadState.EndOfFile;\r
                                return ReadState.Interactive;\r
                        }\r
                }\r
@@ -358,13 +414,8 @@ namespace Mono.Xml.XPath
 \r
                public override void MoveToAttribute (int i)\r
                {\r
-                       XPathNavigator test = GetAttributeNavigator (i);\r
-                       if (test == null)\r
+                       if (!MoveToAttributeNavigator (i))\r
                                throw new ArgumentOutOfRangeException ();\r
-                       else {\r
-                               attributeValueConsumed = false;\r
-                               current = test;\r
-                       }\r
                }\r
 \r
                public override bool MoveToFirstAttribute ()\r
@@ -377,10 +428,14 @@ namespace Mono.Xml.XPath
 \r
                public override bool MoveToNextAttribute ()\r
                {\r
-                       if (current.NodeType != XPathNodeType.Attribute) {\r
+                       if (current.NodeType == XPathNodeType.Namespace) {\r
                                bool b = CheckAttributeMove (current.MoveToNextNamespace (XPathNamespaceScope.Local));\r
                                if (b)\r
                                        return true;\r
+                               current.MoveToParent ();\r
+                               b = CheckAttributeMove (current.MoveToFirstAttribute ());\r
+                               if (b)\r
+                                       return true;\r
                        }\r
                        return CheckAttributeMove (current.MoveToNextAttribute ());\r
                }\r
@@ -403,6 +458,11 @@ namespace Mono.Xml.XPath
 \r
                public override bool Read ()\r
                {\r
+#if NET_2_0\r
+                       if (Binary != null)\r
+                               Binary.Reset ();\r
+#endif\r
+\r
                        switch (ReadState) {\r
                        case ReadState.EndOfFile:\r
                        case ReadState.Closed:\r
@@ -410,8 +470,19 @@ namespace Mono.Xml.XPath
                                return false;\r
                        case ReadState.Initial:\r
                                started = true;\r
-                               if (current.NodeType != XPathNodeType.Root)\r
+                               switch (current.NodeType) {\r
+                               case XPathNodeType.Root:\r
+                                       // recurse, but as Interactive\r
+                                       return Read ();\r
+                               case XPathNodeType.Element:\r
+                                       if (current.IsEmptyElement)\r
+                                               nextIsEOF = true;\r
+                                       attributeCount = GetAttributeCount ();\r
+                                       return true;\r
+                               default:\r
+                                       nextIsEOF = true;\r
                                        return true;\r
+                               }\r
                                break;\r
                        }\r
 \r
@@ -423,12 +494,12 @@ namespace Mono.Xml.XPath
 \r
                        MoveToElement ();\r
 \r
-                       if (endElement || current.MoveToFirstChild () == false) {\r
-                               if (current.MoveToNext () == false) {\r
-                                       if (current.IsSamePosition (root)) {    // It should happen only when the root node was empty.\r
-                                               eof = true;\r
-                                               return false;\r
-                                       }\r
+                       if (endElement || !current.MoveToFirstChild ()) {\r
+                               if (current.IsSamePosition (root)) {    // It should happen only when the root node was empty.\r
+                                       eof = true;\r
+                                       return false;\r
+                               }\r
+                               if (!current.MoveToNext ()) {\r
                                        current.MoveToParent ();\r
                                        depth--;\r
                                        endElement = (current.NodeType == XPathNodeType.Element);\r
@@ -632,3 +703,4 @@ namespace Mono.Xml.XPath
                #endregion\r
        }\r
 }\r
+\r