diff options
Diffstat (limited to 'mcs/class/System.XML/System.Xml/XmlNodeReaderImpl.cs')
-rw-r--r-- | mcs/class/System.XML/System.Xml/XmlNodeReaderImpl.cs | 188 |
1 files changed, 111 insertions, 77 deletions
diff --git a/mcs/class/System.XML/System.Xml/XmlNodeReaderImpl.cs b/mcs/class/System.XML/System.Xml/XmlNodeReaderImpl.cs index 7526bbb71a4..6aa42e07a4b 100644 --- a/mcs/class/System.XML/System.Xml/XmlNodeReaderImpl.cs +++ b/mcs/class/System.XML/System.Xml/XmlNodeReaderImpl.cs @@ -55,11 +55,21 @@ namespace System.Xml XmlDocument document; XmlNode startNode; XmlNode current; - XmlNode ownerLinkedNode; ReadState state = ReadState.Initial; int depth; bool isEndElement; - bool ignoreStartNode; + bool alreadyRead; + + private XmlNode ownerLinkedNode { + get { + if (current.ParentNode != null && current.ParentNode.NodeType == XmlNodeType.Attribute) + return ((XmlAttribute) current.ParentNode).OwnerElement; + else if (current.NodeType == XmlNodeType.Attribute) + return ((XmlAttribute) current).OwnerElement; + else + return current; + } + } #region Constructor @@ -79,7 +89,9 @@ namespace System.Xml case XmlNodeType.Document: case XmlNodeType.DocumentFragment: case XmlNodeType.EntityReference: - ignoreStartNode = true; + break; + default: + alreadyRead = true; break; } @@ -133,15 +145,22 @@ namespace System.Xml public override int Depth { get { - return current == null ? 0 : - current == ownerLinkedNode ? depth : - current.NodeType == XmlNodeType.Attribute ? depth + 1 : - depth + 2; + if (current == null) + return 0; + if (current.NodeType == XmlNodeType.Attribute) + return depth + 1; + if (current.ParentNode != null && current.ParentNode.NodeType == XmlNodeType.Attribute) + return depth + 2; + + return depth; } } public override bool EOF { - get { return state == ReadState.EndOfFile || state == ReadState.Error; } + get { + return this.ReadState == ReadState.EndOfFile + || this.ReadState == ReadState.Error; + } } public override bool HasAttributes { @@ -456,12 +475,9 @@ namespace System.Xml XmlParserContext IHasXmlParserContext.ParserContext { get { return new XmlParserContext (document.NameTable, - current == null ? - new XmlNamespaceManager (document.NameTable) : - current.ConstructNamespaceManager (), + current.ConstructNamespaceManager (), document.DocumentType != null ? document.DocumentType.DTD : null, - current == null ? document.BaseURI : current.BaseURI, - XmlLang, XmlSpace, Encoding.Unicode); + current.BaseURI, XmlLang, XmlSpace, Encoding.Unicode); } } @@ -629,6 +645,14 @@ namespace System.Xml } } + private void MoveToParentElement () + { + // This is buggy. It is not only the case when EndElement = true. + isEndElement = true; + depth--; + current = current.ParentNode; + } + public override bool MoveToElement () { if (current == null) @@ -683,11 +707,29 @@ namespace System.Xml } } + private bool MoveToNextSibling () + { + if (alreadyRead) { + alreadyRead = false; + return current != null; + } + if (current.NextSibling != null) { + isEndElement = false; + current = current.NextSibling; + } else { + MoveToParentElement (); + } + if (current == null) { + state = ReadState.EndOfFile; + return false; + } + else + return true; + } + public override bool Read () { - // FIXME: at some stage inlining might work effectively. - // if (EOF) - if (state == ReadState.EndOfFile || state == ReadState.Error) + if (EOF) return false; #if NET_2_0 @@ -695,19 +737,14 @@ namespace System.Xml Binary.Reset (); #endif - bool ret = ReadContent (); - ownerLinkedNode = current; - return ret; - } - - bool ReadContent () - { if (ReadState == ReadState.Initial) { current = startNode; state = ReadState.Interactive; // when startNode is document or fragment - if (ignoreStartNode) + if (!alreadyRead) current = startNode.FirstChild; + else + alreadyRead = false; if (current == null) { state = ReadState.Error; return false; @@ -717,70 +754,55 @@ namespace System.Xml MoveToElement (); - // don't step into EntityReference's children. Also - // avoid re-entering children of already-consumed - // element (i.e. when it is regarded as EndElement). - XmlNode firstChild = - !isEndElement && current.NodeType != XmlNodeType.EntityReference ? - current.FirstChild : null; - if (firstChild != null) { - isEndElement = false; - current = firstChild; - depth++; - return true; + if (alreadyRead) { + alreadyRead = false; + return current != null; } - if (current == startNode) { // Currently it is on the start node. - if (IsEmptyElement || isEndElement) { - // The start node is already consumed. - isEndElement = false; - current = null; - state = ReadState.EndOfFile; - return false; - } else { - // The start node is the only element - // which should be processed. Now it - // is set as EndElement. + bool isEnd = false; + + if (IsEmptyElement || isEndElement) { + // Then go up and move to next. + // If no more nodes, then set EOF. + isEndElement = false; + if (current.ParentNode == null + || current.ParentNode.NodeType == XmlNodeType.Document + || current.ParentNode.NodeType == XmlNodeType.DocumentFragment + || current == startNode) { + isEnd = true; + } else if (current.NextSibling == null) { + depth--; + current = current.ParentNode; isEndElement = true; return true; + } else { + current = current.NextSibling; + return true; } } - if (!isEndElement && !IsEmptyElement && - current.NodeType == XmlNodeType.Element) { - // element, currently not EndElement, and has - // no child. (such as <foo></foo>, which - // should become EndElement). - isEndElement = true; - return true; - } - // If NextSibling is available, move to there. - XmlNode next = current.NextSibling; - if (next != null) { - isEndElement = false; - current = next; - return true; - } + if (current.NextSibling == null + && current.ParentNode is XmlEntityReference) + isEnd = true; - // Otherwise, parent. - XmlNode parent = current.ParentNode; - if (parent == null || parent == startNode && ignoreStartNode) { - // Parent is not available, or reached to - // the start node. This reader never sets - // startNode as current if it was originally - // ignored (e.g. startNode is XmlDocument). - isEndElement = false; + if (isEnd) { current = null; state = ReadState.EndOfFile; return false; - } else { - // Parent was available, so return it as - // EndElement. - current = parent; - depth--; - isEndElement = true; - return true; } + + if (!isEndElement && current.FirstChild != null && current.NodeType != XmlNodeType.EntityReference) { + isEndElement = false; + current = current.FirstChild; + depth++; + } else if (current.NodeType == XmlNodeType.Element) { + isEndElement = true; + if (current.FirstChild != null) + depth--; + } else + MoveToNextSibling (); + + return current != null; } public override bool ReadAttributeValue () @@ -799,9 +821,21 @@ namespace System.Xml return false; } +#if NET_1_0 + public override string ReadInnerXml () + { + return ReadInnerXmlInternal (); + } + + public override string ReadOuterXml () + { + return ReadOuterXmlInternal (); + } +#endif + public override string ReadString () { - return base.ReadString (); + return ReadStringInternal (); } public override void ResolveEntity () |