TraceXPathNavigator.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / SMDiagnostics / System / ServiceModel / Diagnostics / TraceXPathNavigator.cs / 1 / TraceXPathNavigator.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.ServiceModel.Diagnostics 
{
    using System.Collections.Generic; 
    using System.Diagnostics; 
    using System.Xml;
    using System.Xml.XPath; 
    using System.Globalization;
    using System.Text;
    using System.IO;
 
    // We have to put something here so that when this item appears in the
    // debugger, ToString() isn't called. Calling ToString() can cause bad behavior. 
    [DebuggerDisplay("")] 
    class TraceXPathNavigator : XPathNavigator
    { 
        const int UnlimitedSize = -1;
        ElementNode root = null;
        TraceNode current = null;
        bool closed = false; 
        XPathNodeType state = XPathNodeType.Element;
        int maxSize; 
        long currentSize; 

        public TraceXPathNavigator(int maxSize) 
        {
            this.maxSize = maxSize;
            this.currentSize = 0;
        } 

 
        interface IMeasurable 
        {
            int Size { get; } 
        }

        class TraceNode
        { 
            protected TraceNode(XPathNodeType nodeType, ElementNode parent)
            { 
                this.nodeType = nodeType; 
                this.parent = parent;
            } 

            internal XPathNodeType NodeType
            {
                get { return this.nodeType; } 
            }
 
            XPathNodeType nodeType; 
            internal ElementNode parent;
        } 

        class CommentNode : TraceNode, IMeasurable
        {
            internal CommentNode(string text, ElementNode parent) 
                : base(XPathNodeType.Comment, parent)
            { 
                this.nodeValue = text; 
            }
 
            internal string nodeValue;

            public int Size
            { 
                get
                { 
                    return this.nodeValue.Length + 8; //  
                }
            } 
        }

        class ElementNode : TraceNode, IMeasurable
        { 
            int attributeIndex = 0;
            int elementIndex = 0; 
 
            internal string name;
            internal string prefix; 
            internal string xmlns;
            internal List childNodes = new List();
            internal List attributes = new List();
            internal TextNode text; 
            internal bool movedToText = false;
 
            internal ElementNode(string name, string prefix, ElementNode parent, string xmlns) 
                : base(XPathNodeType.Element, parent)
            { 
                this.name = name;
                this.prefix = prefix;
                this.xmlns = xmlns;
            } 

            internal void Add(TraceNode node) 
            { 
                this.childNodes.Add(node);
            } 

            //This method returns all subnodes with the given path of local names. Namespaces are ignored.
            //For all path elements but the last one, the first match is taken. For the last path element, all matches are returned.
            internal IEnumerable FindSubnodes(string[] headersPath) 
            {
#pragma warning disable 618 
                AssertUtility.DebugAssert(null != headersPath, "Headers path should not be null"); 
                AssertUtility.DebugAssert(headersPath.Length > 0, "There should be more than one item in the headersPath array.");
#pragma warning restore 618 

                if (null == headersPath)
                {
                    throw new ArgumentNullException("headersPath"); 
                }
                ElementNode node = this; 
                if (String.CompareOrdinal(node.name, headersPath[0]) != 0) 
                {
                    node = null; 
                }
                int i = 0;
                while (null != node && ++i < headersPath.Length)
                { 
#pragma warning disable 618
                    AssertUtility.DebugAssert(null != headersPath[i], "None of the elements in headersPath should be null."); 
#pragma warning restore 618 
                    ElementNode subNode = null;
                    if (null != node.childNodes) 
                    {
                        foreach (TraceNode child in node.childNodes)
                        {
                            if (child.NodeType == XPathNodeType.Element) 
                            {
                                ElementNode childNode = child as ElementNode; 
                                if (null != childNode && 0 == String.CompareOrdinal(childNode.name, headersPath[i])) 
                                {
                                    if (headersPath.Length == i + 1) 
                                    {
                                        yield return childNode;
                                    }
                                    else 
                                    {
                                        subNode = childNode; 
                                        break; 
                                    }
                                } 
                            }
                        }
                    }
 
                    node = subNode;
                } 
            } 

            internal TraceNode MoveToNext() 
            {
                TraceNode retval = null;
                if ((this.elementIndex + 1) < this.childNodes.Count)
                { 
                    ++this.elementIndex;
                    retval = this.childNodes[this.elementIndex]; 
                } 
                return retval;
            } 

            internal bool MoveToFirstAttribute()
            {
                this.attributeIndex = 0; 
                return null != this.attributes && this.attributes.Count > 0;
            } 
 
            internal bool MoveToNextAttribute()
            { 
                bool retval = false;
                if ((this.attributeIndex + 1) < this.attributes.Count)
                {
                    ++this.attributeIndex; 
                    retval = true;
                } 
                return retval; 
            }
 
            internal void Reset()
            {
                this.attributeIndex = 0;
                this.elementIndex = 0; 
                this.movedToText = false;
                if (null != this.childNodes) 
                { 
                    foreach (TraceNode node in this.childNodes)
                    { 
                        if (node.NodeType == XPathNodeType.Element)
                        {
                            ElementNode child = node as ElementNode;
                            if (child != null) 
                            {
                                child.Reset(); 
                            } 
                        }
                    } 
                }
            }

            internal AttributeNode CurrentAttribute 
            {
                get 
                { 
                    return this.attributes[this.attributeIndex];
                } 
            }

            public int Size
            { 
                get
                { 
                    int size = 2 * this.name.Length + 6; //upper bound  
                    if (!string.IsNullOrEmpty(this.prefix))
                    { 
                        size += this.prefix.Length + 1;
                    }
                    if (!string.IsNullOrEmpty(this.xmlns))
                    { 
                        size += this.xmlns.Length + 9;  // xmlns="xmlns"
                    } 
                    return size; 
                }
            } 
        }

        class AttributeNode : IMeasurable
        { 
            internal AttributeNode(string name, string prefix, string value, string xmlns)
            { 
                this.name = name; 
                this.prefix = prefix;
                this.nodeValue = value; 
                this.xmlns = xmlns;
            }

            internal string name; 
            internal string nodeValue;
            internal string prefix; 
            internal string xmlns; 

            public int Size 
            {
                get
                {
                    int size = this.name.Length + this.nodeValue.Length + 5; 

                    if (!string.IsNullOrEmpty(this.prefix)) 
                    { 
                        size += this.prefix.Length + 1;
                    } 

                    if (!string.IsNullOrEmpty(this.xmlns))
                    {
                        size += this.xmlns.Length + 9; //upper bound 
                    }
 
                    return size; 
                }
            } 
        }

        class ProcessingInstructionNode : TraceNode, IMeasurable
        { 
            internal ProcessingInstructionNode(string name, string text, ElementNode parent)
                : 
                base(XPathNodeType.ProcessingInstruction, parent) 
            {
                this.name = name; 
                this.text = text;
            }

            internal string name; 
            internal string text;
 
            public int Size 
            {
                get 
                {
                    return this.name.Length + this.text.Length + 12; //
                }
            } 
        }
 
        class TextNode : IMeasurable 
        {
            internal TextNode(string value) 
            {
                this.nodeValue = value;
            }
            internal string nodeValue; 

            public int Size 
            { 
                get
                { 
                    return this.nodeValue.Length;
                }
            }
        } 

        internal void AddElement(string prefix, string name, string xmlns) 
        { 
            if (this.closed)
            { 
#pragma warning disable 618
                AssertUtility.DebugAssert("Cannot add data to a closed document");
#pragma warning restore 618
                throw new InvalidOperationException(); 
            }
            else 
            { 
                ElementNode node = new ElementNode(name, prefix, this.CurrentElement, xmlns);
                if (this.current == null) 
                {
                    this.VerifySize(node);
                    this.root = node;
                    this.current = this.root; 
                }
                else if (!this.closed) 
                { 
                    this.VerifySize(node);
                    this.CurrentElement.Add(node); 
                    this.current = node;
                }
            }
        } 

        internal void AddProcessingInstruction(string name, string text) 
        { 
            if (this.current == null)
            { 
                return;
            }
            else
            { 
                ProcessingInstructionNode node = new ProcessingInstructionNode(name, text, this.CurrentElement);
                this.VerifySize(node); 
                this.CurrentElement.Add(node); 
            }
        } 

        internal void AddText(string value)
        {
            if (this.closed) 
            {
#pragma warning disable 618 
                AssertUtility.DebugAssert("Cannot add data to a closed document"); 
#pragma warning restore 618
                throw new InvalidOperationException(); 
            }
            if (this.current == null)
            {
                return; 
            }
            else 
            { 
                if (this.CurrentElement.text == null)
                { 
                    TextNode node = new TextNode(value);
                    this.VerifySize(node);
                    this.CurrentElement.text = node;
                } 
                else if (!string.IsNullOrEmpty(value))
                { 
                    this.VerifySize(value); 
                    this.CurrentElement.text.nodeValue += value;
                } 
            }
        }

        internal void AddAttribute(string name, string value, string xmlns, string prefix) 
        {
            if (this.closed) 
            { 
#pragma warning disable 618
                AssertUtility.DebugAssert("Cannot add data to a closed document"); 
#pragma warning restore 618
                throw new InvalidOperationException();
            }
            if (this.current == null) 
            {
#pragma warning disable 618 
                AssertUtility.DebugAssert("Operation is invalid on an empty document"); 
#pragma warning restore 618
                throw new InvalidOperationException(); 
            }
            AttributeNode node = new AttributeNode(name, prefix, value, xmlns);
            this.VerifySize(node);
            this.CurrentElement.attributes.Add(node); 
        }
 
        internal void AddComment(string text) 
        {
            if (this.closed) 
            {
#pragma warning disable 618
                AssertUtility.DebugAssert("Cannot add data to a closed document");
#pragma warning restore 618 
                throw new InvalidOperationException();
            } 
            if (this.current == null) 
            {
#pragma warning disable 618 
                AssertUtility.DebugAssert("Operation is invalid on an empty document");
#pragma warning restore 618
                throw new InvalidOperationException();
            } 
            CommentNode node = new CommentNode(text, this.CurrentElement);
            this.VerifySize(node); 
            this.CurrentElement.Add(node); 
        }
 
        internal void CloseElement()
        {
            if (this.closed)
            { 
#pragma warning disable 618
                AssertUtility.DebugAssert("The document is already closed."); 
#pragma warning restore 618 
                throw new InvalidOperationException();
            } 
            else
            {
                this.current = this.CurrentElement.parent;
                if (this.current == null) 
                {
                    this.closed = true; 
                } 
            }
        } 

        public override string BaseURI
        {
            get { return String.Empty; } 
        }
 
        public override XPathNavigator Clone() 
        {
            return this; 
        }

        public override bool IsEmptyElement
        { 
            get
            { 
                bool retval = true; 
                if (this.current != null)
                { 
                    retval = this.CurrentElement.text != null || this.CurrentElement.childNodes.Count > 0;
                }
                return retval;
            } 
        }
 
        public override bool IsSamePosition(XPathNavigator other) 
        {
            return false; 
        }

        [DebuggerDisplay("")]
        public override string LocalName 
        {
            get { return this.Name; } 
        } 

        public override string LookupPrefix(string ns) 
        {
            return this.LookupPrefix(ns, this.CurrentElement);
        }
 
        string LookupPrefix(string ns, ElementNode node)
        { 
            string retval = null; 
            if (string.Compare(ns, node.xmlns, StringComparison.Ordinal) == 0)
            { 
                retval = node.prefix;
            }
            else
            { 
                foreach (AttributeNode attributeNode in node.attributes)
                { 
                    if (string.Compare("xmlns", attributeNode.prefix, StringComparison.Ordinal) == 0) 
                    {
                        if (string.Compare(ns, attributeNode.nodeValue, StringComparison.Ordinal) == 0) 
                        {
                            retval = attributeNode.name;
                            break;
                        } 
                    }
                } 
            } 

            if (string.IsNullOrEmpty(retval) && node.parent != null) 
            {
                retval = LookupPrefix(ns, node.parent);
            }
            return retval; 
        }
 
        public override bool MoveTo(XPathNavigator other) 
        {
            return false; 
        }

        public override bool MoveToFirstAttribute()
        { 
            if (this.current == null)
            { 
#pragma warning disable 618 
                AssertUtility.DebugAssert("Operation is invalid on an empty document");
#pragma warning restore 618 
                throw new InvalidOperationException();
            }
            bool retval = this.CurrentElement.MoveToFirstAttribute();
            if (retval) 
            {
                this.state = XPathNodeType.Attribute; 
            } 
            return retval;
        } 

        public override bool MoveToFirstChild()
        {
            if (this.current == null) 
            {
#pragma warning disable 618 
                AssertUtility.DebugAssert("Operation is invalid on an empty document"); 
#pragma warning restore 618
                throw new InvalidOperationException(); 
            }
            bool retval = false;
            if (null != this.CurrentElement.childNodes && this.CurrentElement.childNodes.Count > 0)
            { 
                this.current = this.CurrentElement.childNodes[0];
                this.state = this.current.NodeType; 
                retval = true; 
            }
            else if ((null == this.CurrentElement.childNodes || this.CurrentElement.childNodes.Count == 0) && this.CurrentElement.text != null) 
            {
                this.state = XPathNodeType.Text;
                this.CurrentElement.movedToText = true;
                retval = true; 
            }
            return retval; 
        } 

        public override bool MoveToFirstNamespace(XPathNamespaceScope namespaceScope) 
        {
            return false;
        }
 
        public override bool MoveToId(string id)
        { 
            return false; 
        }
 
        public override bool MoveToNext()
        {
            if (this.current == null)
            { 
#pragma warning disable 618
                AssertUtility.DebugAssert("Operation is invalid on an empty document"); 
#pragma warning restore 618 
                throw new InvalidOperationException();
            } 
            bool retval = false;
            if (this.state != XPathNodeType.Text)
            {
                ElementNode parent = this.current.parent; 
                if (parent != null)
                { 
                    TraceNode temp = parent.MoveToNext(); 
                    if (temp == null && parent.text != null && !parent.movedToText)
                    { 
                        this.state = XPathNodeType.Text;
                        parent.movedToText = true;
                        this.current = parent;
                        retval = true; 
                    }
                    else if (temp != null) 
                    { 
                        this.state = temp.NodeType;
                        retval = true; 
                        this.current = temp;
                    }
                }
            } 
            return retval;
        } 
 
        public override bool MoveToNextAttribute()
        { 
            if (this.current == null)
            {
#pragma warning disable 618
                AssertUtility.DebugAssert("Operation is invalid on an empty document"); 
#pragma warning restore 618
                throw new InvalidOperationException(); 
            } 
            bool retval = this.CurrentElement.MoveToNextAttribute();
            if (retval) 
            {
                this.state = XPathNodeType.Attribute;
            }
            return retval; 
        }
 
        public override bool MoveToNextNamespace(XPathNamespaceScope namespaceScope) 
        {
            return false; 
        }

        public override bool MoveToParent()
        { 
            if (this.current == null)
            { 
#pragma warning disable 618 
                AssertUtility.DebugAssert("Operation is invalid on an empty document");
#pragma warning restore 618 
                throw new InvalidOperationException();
            }
            bool retval = false;
            switch (this.state) 
            {
                case XPathNodeType.Comment: 
                case XPathNodeType.Element: 
                case XPathNodeType.ProcessingInstruction:
                    if (this.current.parent != null) 
                    {
                        this.current = this.current.parent;
                        this.state = this.current.NodeType;
                        retval = true; 
                    }
                    break; 
                case XPathNodeType.Attribute: 
                    this.state = XPathNodeType.Element;
                    retval = true; 
                    break;
                case XPathNodeType.Text:
                    this.state = XPathNodeType.Element;
                    retval = true; 
                    break;
                case XPathNodeType.Namespace: 
                    this.state = XPathNodeType.Element; 
                    retval = true;
                    break; 
            }
            return retval;
        }
 
        public override bool MoveToPrevious()
        { 
            return false; 
        }
 
        public override void MoveToRoot()
        {
            this.current = this.root;
            this.state = XPathNodeType.Element; 
            this.root.Reset();
        } 
 
        [DebuggerDisplay("")]
        public override string Name 
        {
            get
            {
                string retval = String.Empty; 
                if (this.current == null)
                { 
#pragma warning disable 618 
                    AssertUtility.DebugAssert("Operation is invalid on an empty document");
#pragma warning restore 618 
                }
                else
                {
                    switch (this.state) 
                    {
                        case XPathNodeType.Attribute: 
                            retval = this.CurrentElement.CurrentAttribute.name; 
                            break;
                        case XPathNodeType.Element: 
                            retval = this.CurrentElement.name;
                            break;
                        case XPathNodeType.ProcessingInstruction:
                            retval = this.CurrentProcessingInstruction.name; 
                            break;
                    } 
                } 
                return retval;
            } 
        }

        public override System.Xml.XmlNameTable NameTable
        { 
            get { return null; }
        } 
 
        [DebuggerDisplay("")]
        public override string NamespaceURI 
        {
            get
            {
                string retval = String.Empty; 
                if (this.current == null)
                { 
#pragma warning disable 618 
                    AssertUtility.DebugAssert("Operation is invalid on an empty document");
#pragma warning restore 618 
                }
                else
                {
                    switch (this.state) 
                    {
                        case XPathNodeType.Element: 
                            retval = this.CurrentElement.xmlns; 
                            break;
                        case XPathNodeType.Attribute: 
                            retval = this.CurrentElement.CurrentAttribute.xmlns;
                            break;
                        case XPathNodeType.Namespace:
                            retval = null; 
                            break;
                    } 
                } 
                return retval;
            } 
        }

        [DebuggerDisplay("")]
        public override XPathNodeType NodeType 
        {
            get { return this.state; } 
        } 

        [DebuggerDisplay("")] 
        public override string Prefix
        {
            get
            { 
                string retval = String.Empty;
                if (this.current == null) 
                { 
#pragma warning disable 618
                    AssertUtility.DebugAssert("Operation is invalid on an empty document"); 
#pragma warning restore 618
                }
                else
                { 
                    switch (this.state)
                    { 
                        case XPathNodeType.Element: 
                            retval = this.CurrentElement.prefix;
                            break; 
                        case XPathNodeType.Attribute:
                            retval = this.CurrentElement.CurrentAttribute.prefix;
                            break;
                        case XPathNodeType.Namespace: 
                            retval = null;
                            break; 
                    } 
                }
                return retval; 
            }
        }

        CommentNode CurrentComment 
        {
            get { return this.current as CommentNode; } 
        } 

        ElementNode CurrentElement 
        {
            get { return this.current as ElementNode; }
        }
 
        ProcessingInstructionNode CurrentProcessingInstruction
        { 
            get { return this.current as ProcessingInstructionNode; } 
        }
 
        [DebuggerDisplay("")]
        public override string Value
        {
            get 
            {
                string retval = String.Empty; 
                if (this.current == null) 
                {
#pragma warning disable 618 
                    AssertUtility.DebugAssert("Operation is invalid on an empty document");
#pragma warning restore 618
                }
                else 
                {
                    switch (this.state) 
                    { 
                        case XPathNodeType.Text:
                            retval = this.CurrentElement.text.nodeValue; 
                            break;
                        case XPathNodeType.Attribute:
                            retval = this.CurrentElement.CurrentAttribute.nodeValue;
                            break; 
                        case XPathNodeType.Comment:
                            retval = this.CurrentComment.nodeValue; 
                            break; 
                        case XPathNodeType.ProcessingInstruction:
                            retval = this.CurrentProcessingInstruction.text; 
                            break;
                    }
                }
                return retval; 
            }
        } 
 
        internal WriteState WriteState
        { 
            get
            {
                WriteState retval = WriteState.Error;
                if (this.current == null) 
                {
                    retval = WriteState.Start; 
                } 
                else if (this.closed)
                { 
                    retval = WriteState.Closed;
                }
                else
                { 
                    switch (this.state)
                    { 
                        case XPathNodeType.Attribute: 
                            retval = WriteState.Attribute;
                            break; 
                        case XPathNodeType.Element:
                            retval = WriteState.Element;
                            break;
                        case XPathNodeType.Text: 
                            retval = WriteState.Content;
                            break; 
                        case XPathNodeType.Comment: 
                            retval = WriteState.Content;
                            break; 
                    }
                }
                return retval;
            } 
        }
 
        public override string ToString() 
        {
            this.MoveToRoot(); 
            StringBuilder sb = new StringBuilder();
            XmlTextWriter writer = new XmlTextWriter(new StringWriter(sb, CultureInfo.CurrentCulture));
            writer.WriteNode(this, false);
            return sb.ToString(); 
        }
 
        void VerifySize(IMeasurable node) 
        {
            this.VerifySize(node.Size); 
        }

        void VerifySize(string node)
        { 
            this.VerifySize(node.Length);
        } 
 
        void VerifySize(int nodeSize)
        { 
            if (this.maxSize != TraceXPathNavigator.UnlimitedSize)
            {
                if (this.currentSize + nodeSize > this.maxSize)
                { 
                    throw new PlainXmlWriter.MaxSizeExceededException();
                } 
            } 
            this.currentSize += nodeSize;
        } 

        public void RemovePii(string[][] paths)
        {
#pragma warning disable 618 
            AssertUtility.DebugAssert(null != paths, "");
#pragma warning restore 618 
            if (paths == null) 
            {
                throw new ArgumentNullException("paths"); 
            }

            foreach (string[] path in paths)
            { 
                RemovePii(path);
            } 
        } 

        public void RemovePii(string[] path) 
        {
            RemovePii(path, DiagnosticStrings.PiiList);
        }
 
        public void RemovePii(string[] headersPath, string[] piiList)
        { 
#pragma warning disable 618 
            AssertUtility.DebugAssert(null != this.root, "");
            if (this.root == null) 
            {
                throw new InvalidOperationException();
            }
            foreach (ElementNode node in this.root.FindSubnodes(headersPath)) 
            {
                AssertUtility.DebugAssert(null != node, ""); 
                MaskSubnodes(node, piiList); 
            }
        } 
#pragma warning restore 618

        static void MaskElement(ElementNode element)
        { 
            if (null != element)
            { 
                element.childNodes.Clear(); 
                element.Add(new CommentNode("Removed", element));
                element.text = null; 
                element.attributes = null;
            }
        }
 
        static void MaskSubnodes(ElementNode element, string[] elementNames)
        { 
            MaskSubnodes(element, elementNames, false); 
        }
 
        static void MaskSubnodes(ElementNode element, string[] elementNames, bool processNodeItself)
        {
#pragma warning disable 618
            AssertUtility.DebugAssert(null != elementNames, ""); 
#pragma warning restore 618
            if (elementNames == null) 
            { 
                throw new ArgumentNullException("elementNames");
            } 

            if (null != element)
            {
                bool recurse = true; 
                if (processNodeItself)
                { 
                    foreach (string elementName in elementNames) 
                    {
#pragma warning disable 618 
                        AssertUtility.DebugAssert(!String.IsNullOrEmpty(elementName), "");
#pragma warning restore 618
                        if (0 == String.CompareOrdinal(elementName, element.name))
                        { 
                            MaskElement(element);
                            recurse = false; 
                            break; 
                        }
                    } 
                }
                if (recurse)
                {
                    if (null != element.childNodes) 
                    {
                        foreach (ElementNode subNode in element.childNodes) 
                        { 
#pragma warning disable 618
                            AssertUtility.DebugAssert(null != subNode, ""); 
#pragma warning restore 618
                            MaskSubnodes(subNode, elementNames, true);
                        }
                    } 
                }
            } 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK