2004-07-29 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Thu, 29 Jul 2004 14:32:10 +0000 (14:32 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Thu, 29 Jul 2004 14:32:10 +0000 (14:32 -0000)
* XPathNavigatorReader.cs :
  - it is used only in 2.0 classes.
  - It now behaves as a fragment reader.
  - Depth is optimized not to call Clone() and MoveToParent().
  - AttributeCount could be counted only once in Read().
  - ReadState transition is adjusted to be same as other XmlReaders.
  - name strings now return "" on initial state.

svn path=/trunk/mcs/; revision=31608

mcs/class/System.XML/Mono.Xml.XPath/ChangeLog
mcs/class/System.XML/Mono.Xml.XPath/XPathNavigatorReader.cs

index 31f68a058683ef575e2bcb5c0fe04b22748cf27b..bfd13f37e5567355d5c74eca6687a3cca0bcc42f 100644 (file)
@@ -1,3 +1,13 @@
+2004-07-29  Atsushi Enomoto <atsushi@ximian.com>
+
+       * XPathNavigatorReader.cs :
+         - it is used only in 2.0 classes.
+         - It now behaves as a fragment reader.
+         - Depth is optimized not to call Clone() and MoveToParent().
+         - AttributeCount could be counted only once in Read().
+         - ReadState transition is adjusted to be same as other XmlReaders.
+         - name strings now return "" on initial state.
+
 2004-07-28  Atsushi Enomoto <atsushi@ximian.com>
 
        * Added XPathEditableDocument.cs.
index 036722f9f89b4babaf4fdcef320c4159ef9f26e8..2937062ead1d26c3864fadab73b280769e2f3939 100755 (executable)
@@ -40,7 +40,6 @@ namespace Mono.Xml.XPath
                public XPathNavigatorReader (XPathNavigator nav)\r
                {\r
                        root = nav.Clone ();\r
-                       root.MoveToRoot ();\r
                        current = nav.Clone ();\r
                }\r
 \r
@@ -53,6 +52,11 @@ namespace Mono.Xml.XPath
                StringBuilder readStringBuffer = new StringBuilder ();\r
                StringBuilder innerXmlBuilder = new StringBuilder ();\r
 \r
+               int depth = 0;\r
+               int attributeCount = 0;\r
+               bool eof;\r
+               bool nextIsEOF;\r
+\r
                #region Properties\r
                public override XmlNodeType NodeType \r
                {\r
@@ -87,19 +91,19 @@ namespace Mono.Xml.XPath
                }\r
 \r
                public override string Name {\r
-                       get { return current.Name; }\r
+                       get { return eof ? String.Empty : current.Name; }\r
                }\r
 \r
                public override string LocalName {\r
-                       get { return current.LocalName; }\r
+                       get { return eof ? String.Empty : current.LocalName; }\r
                }\r
 \r
                public override string NamespaceURI {\r
-                       get { return current.NamespaceURI; }\r
+                       get { return eof ? String.Empty : current.NamespaceURI; }\r
                }\r
 \r
                public override string Prefix {\r
-                       get { return current.Prefix; }\r
+                       get { return eof ? String.Empty : current.Prefix; }\r
                }\r
 \r
                public override bool HasValue {\r
@@ -120,14 +124,11 @@ namespace Mono.Xml.XPath
 \r
                public override int Depth {\r
                        get {\r
-                               if (current.IsSamePosition (root))\r
+                               switch (ReadState) {\r
+                               case ReadState.EndOfFile:\r
+                               case ReadState.Initial:\r
+                               case ReadState.Closed:\r
                                        return 0;\r
-                               XPathNavigator tmp = current.Clone ();\r
-                               // top level nodes' depth = 0.\r
-                               int depth = -1;\r
-                               while (!tmp.IsSamePosition (root)) {\r
-                                       tmp.MoveToParent ();\r
-                                       depth ++;\r
                                }\r
                                return depth;\r
                        }\r
@@ -181,36 +182,25 @@ namespace Mono.Xml.XPath
                }\r
 \r
                public override int AttributeCount {\r
-                       get {\r
-                               XPathNavigator backup = null;\r
-                               try {\r
-                                       switch (current.NodeType) {\r
-                                       case XPathNodeType.Namespace:\r
-                                       case XPathNodeType.Attribute:\r
-                                               backup = current.Clone ();\r
-                                               current.MoveToParent ();\r
-                                               goto case XPathNodeType.Element;\r
-                                       case XPathNodeType.Element:\r
-                                               int count = 0;\r
-                                               if (current.MoveToFirstAttribute ())\r
-                                                       do {\r
-                                                               count++;\r
-                                                       } while (current.MoveToNextAttribute ());\r
-                                               current.MoveToParent ();\r
-                                               if (current.MoveToFirstNamespace (XPathNamespaceScope.Local))\r
-                                                       do {\r
-                                                               count++;\r
-                                                       } while (current.MoveToNextNamespace (XPathNamespaceScope.Local));\r
-                                               current.MoveToParent ();\r
-                                               return count;\r
-                                       }\r
-                                       // default\r
-                                       return 0;\r
-                               } finally {\r
-                                       if (backup != null)\r
-                                               current = backup;\r
-                               }\r
+                       get { return attributeCount; }\r
+               }\r
+\r
+               private int GetAttributeCount ()\r
+               {\r
+                       int count = 0;\r
+                       if (current.MoveToFirstAttribute ()) {\r
+                               do {\r
+                                       count++;\r
+                               } while (current.MoveToNextAttribute ());\r
+                               current.MoveToParent ();\r
+                       }\r
+                       if (current.MoveToFirstNamespace (XPathNamespaceScope.Local)) {\r
+                               do {\r
+                                       count++;\r
+                               } while (current.MoveToNextNamespace (XPathNamespaceScope.Local));\r
+                               current.MoveToParent ();\r
                        }\r
+                       return count;\r
                }\r
                \r
                private XPathNavigator GetAttributeNavigator (int i)\r
@@ -276,7 +266,7 @@ namespace Mono.Xml.XPath
 \r
                public override bool EOF {\r
                        get {\r
-                               return ReadState == ReadState.EndOfFile;\r
+                               return eof || ReadState == ReadState.EndOfFile;\r
                        }\r
                }\r
 \r
@@ -284,9 +274,9 @@ namespace Mono.Xml.XPath
                        get {\r
                                if (closed)\r
                                        return ReadState.Closed;\r
-                               if (!started)\r
+                               else if (!started)\r
                                        return ReadState.Initial;\r
-                               else if (current.IsSamePosition (root))\r
+                               else if (eof)\r
                                        return ReadState.EndOfFile;\r
                                return ReadState.Interactive;\r
                        }\r
@@ -394,9 +384,8 @@ namespace Mono.Xml.XPath
 \r
                public override void Close ()\r
                {\r
-                       // It is kinda hack to make ReadState EOF.\r
-                       current = root;\r
                        closed = true;\r
+                       eof = true;\r
                }\r
 \r
                public override bool Read ()\r
@@ -406,19 +395,45 @@ namespace Mono.Xml.XPath
                        case ReadState.Closed:\r
                        case ReadState.Error:\r
                                return false;\r
+                       case ReadState.Initial:\r
+                               started = true;\r
+                               if (current.NodeType != XPathNodeType.Root)\r
+                                       return true;\r
+                               break;\r
+                       }\r
+\r
+                       if (nextIsEOF) {\r
+                               nextIsEOF = false;\r
+                               eof = true;\r
+                               return false;\r
                        }\r
-                       started = true;\r
-                       this.MoveToElement ();\r
+\r
+                       MoveToElement ();\r
 \r
                        if (endElement || current.MoveToFirstChild () == false) {\r
                                if (current.MoveToNext () == false) {\r
-                                       current.MoveToParent ();\r
-                                       if (ReadState == ReadState.EndOfFile)\r
+                                       if (current.IsSamePosition (root)) {    // It should happen only when the root node was empty.\r
+                                               eof = true;\r
                                                return false;\r
-                                       endElement = true;\r
+                                       }\r
+                                       current.MoveToParent ();\r
+                                       depth--;\r
+                                       if (current.IsSamePosition (root)) {\r
+                                               if (current.NodeType == XPathNodeType.Element)\r
+                                                       nextIsEOF = true;\r
+                                               else {\r
+                                                       eof = true;\r
+                                                       return false;\r
+                                               }\r
+                                       }\r
+                                       if (current.NodeType == XPathNodeType.Element)\r
+                                               endElement = true;\r
                                } else\r
                                        endElement = false;\r
                        }\r
+                       else if (!endElement)\r
+                               depth++;\r
+                       attributeCount = GetAttributeCount ();\r
                        return true;\r
                }\r
 \r