XamlDebuggerXmlReader.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.Activities / System / Activities / Debugger / XamlDebuggerXmlReader.cs / 1305376 / XamlDebuggerXmlReader.cs

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

namespace System.Activities.Debugger 
{
    using System.Activities.XamlIntegration; 
    using System.Collections.Generic; 
    using System.ComponentModel;
    using System.Diagnostics.CodeAnalysis; 
    using System.Xml.Linq;
    using System.Xaml;
    using System.Xaml.Schema;
    using System.Runtime; 
    using System.Text;
    using System.Globalization; 
    using System.Linq; 
    using System.Windows.Markup;
    using System.IO; 

    // This class never be serialized.
    [Fx.Tag.XamlVisible(false)]
    public class XamlDebuggerXmlReader : XamlReader, IXamlLineInfo 
    {
        static Type attachingTypeName = typeof(XamlDebuggerXmlReader); 
 
        XamlSchemaContext xsc;
        XamlType attachingXamlTypeName; 

        [SuppressMessage(FxCop.Category.Security, FxCop.Rule.DoNotDeclareReadOnlyMutableReferenceTypes)]
        public static readonly AttachableMemberIdentifier StartLineName = new AttachableMemberIdentifier(attachingTypeName, "StartLine");
 
        [SuppressMessage(FxCop.Category.Security, FxCop.Rule.DoNotDeclareReadOnlyMutableReferenceTypes)]
        public static readonly AttachableMemberIdentifier StartColumnName = new AttachableMemberIdentifier(attachingTypeName, "StartColumn"); 
 
        [SuppressMessage(FxCop.Category.Security, FxCop.Rule.DoNotDeclareReadOnlyMutableReferenceTypes)]
        public static readonly AttachableMemberIdentifier EndLineName = new AttachableMemberIdentifier(attachingTypeName, "EndLine"); 

        [SuppressMessage(FxCop.Category.Security, FxCop.Rule.DoNotDeclareReadOnlyMutableReferenceTypes)]
        public static readonly AttachableMemberIdentifier EndColumnName = new AttachableMemberIdentifier(attachingTypeName, "EndColumn");
 
        [SuppressMessage(FxCop.Category.Security, FxCop.Rule.DoNotDeclareReadOnlyMutableReferenceTypes)]
        public static readonly AttachableMemberIdentifier FileNameName = new AttachableMemberIdentifier(attachingTypeName, "FileName"); 
 
        XamlValidatingReader underlyingReader;
        Stack records; 
        Stack lineInfoStateStack; // Stack for LineInfoStateReader
        ReadState state;
        XamlNode current;
        BracketLocator bracketLocator; 
        readonly bool hasLineInfo;
 
        public XamlDebuggerXmlReader(XamlReader underlyingReader, TextReader textReader) 
            : this(underlyingReader, underlyingReader as IXamlLineInfo, textReader)
        { 
        }

        public XamlDebuggerXmlReader(XamlReader underlyingReader, IXamlLineInfo xamlLineInfo, TextReader textReader)
        { 
            this.underlyingReader = new XamlValidatingReader(underlyingReader, xamlLineInfo);
            this.xsc = underlyingReader.SchemaContext; 
            this.attachingXamlTypeName = new XamlType(attachingTypeName, xsc); 
            this.records = new Stack();
            this.lineInfoStateStack = new Stack(); 
            this.state = InReaderState.Instance;
            this.hasLineInfo = xamlLineInfo != null && xamlLineInfo.HasLineInfo;
            if (xamlLineInfo != null && xamlLineInfo.HasLineInfo && textReader != null)
            { 
                this.bracketLocator = new BracketLocator(textReader);
            } 
        } 

        public bool HasLineInfo 
        {
            get
            {
                return this.hasLineInfo; 
            }
        } 
 
        public int LineNumber
        { 
            get
            {
                if (this.hasLineInfo)
                { 
                    return this.Current.LineNumber;
                } 
                return 0; 
            }
        } 

        public int LinePosition
        {
            get 
            {
                if (this.hasLineInfo) 
                { 
                    return this.Current.LinePosition;
                } 
                return 0;
            }
        }
 
        XamlNode Current
        { 
            get 
            {
                return this.current; 
            }
        }

        public override XamlMember Member 
        {
            get 
            { 
                XamlStartMemberNode node = this.current as XamlStartMemberNode;
                XamlMember member = node.Member; 
                return member;
            }
        }
 
        public override XamlNodeType NodeType
        { 
            get 
            {
                return this.current.NodeType; 
            }
        }

        public override XamlType Type 
        {
            get 
            { 
                XamlStartRecordNode node = this.current as XamlStartRecordNode;
                XamlType xamlType = node.RecordType; 
                return xamlType;
            }
        }
 
        public override object Value
        { 
            get 
            {
                XamlAtomNode node = this.current as XamlAtomNode; 
                return node.Value;
            }
        }
 
        public override bool IsEof
        { 
            get 
            {
                return this.underlyingReader.EndOfInput; 
            }
        }

        public override NamespaceDeclaration Namespace 
        {
            get 
            { 
                XamlNamespaceNode namespaceNode = this.current as XamlNamespaceNode;
                return namespaceNode.Namespace; 
            }
        }

        public override XamlSchemaContext SchemaContext 
        {
            get { return this.xsc; } 
        } 

        [Fx.Tag.InheritThrows(From = "TryGetProperty", FromDeclaringType = typeof(AttachablePropertyServices))] 
        static int GetIntegerAttachedProperty(object instance, AttachableMemberIdentifier memberIdentifier)
        {
            int value;
            if (AttachablePropertyServices.TryGetProperty(instance, memberIdentifier, out value)) 
            {
                return value; 
            } 
            else
            { 
                return -1;
            }
        }
 
        [Fx.Tag.InheritThrows(From = "GetIntegerAttachedProperty")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public static object GetStartLine(object instance) 
        {
            return GetIntegerAttachedProperty(instance, StartLineName); 
        }

        [Fx.Tag.InheritThrows(From = "SetProperty", FromDeclaringType = typeof(AttachablePropertyServices))]
        public static void SetStartLine(object instance, object value) 
        {
            AttachablePropertyServices.SetProperty(instance, StartLineName, value); 
        } 

        [Fx.Tag.InheritThrows(From = "GetIntegerAttachedProperty")] 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public static object GetStartColumn(object instance)
        {
            return GetIntegerAttachedProperty(instance, StartColumnName); 
        }
 
        [Fx.Tag.InheritThrows(From = "SetProperty", FromDeclaringType = typeof(AttachablePropertyServices))] 
        public static void SetStartColumn(object instance, object value)
        { 
            AttachablePropertyServices.SetProperty(instance, StartColumnName, value);
        }

        [Fx.Tag.InheritThrows(From = "GetIntegerAttachedProperty")] 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public static object GetEndLine(object instance) 
        { 
            return GetIntegerAttachedProperty(instance, EndLineName);
        } 

        [Fx.Tag.InheritThrows(From = "SetProperty", FromDeclaringType = typeof(AttachablePropertyServices))]
        public static void SetEndLine(object instance, object value)
        { 
            AttachablePropertyServices.SetProperty(instance, EndLineName, value);
        } 
 
        [Fx.Tag.InheritThrows(From = "GetIntegerAttachedProperty")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public static object GetEndColumn(object instance)
        {
            return GetIntegerAttachedProperty(instance, EndColumnName);
        } 

        [Fx.Tag.InheritThrows(From = "SetProperty", FromDeclaringType = typeof(AttachablePropertyServices))] 
        public static void SetEndColumn(object instance, object value) 
        {
            AttachablePropertyServices.SetProperty(instance, EndColumnName, value); 
        }

        [Fx.Tag.InheritThrows(From = "SetProperty", FromDeclaringType = typeof(AttachablePropertyServices))]
        public static void SetFileName(object instance, object value) 
        {
            AttachablePropertyServices.SetProperty(instance, FileNameName, value); 
        } 

        [Fx.Tag.InheritThrows(From = "TryGetProperty", FromDeclaringType = typeof(AttachablePropertyServices))] 
        public static object GetFileName(object instance)
        {
            string value;
            if (AttachablePropertyServices.TryGetProperty(instance, FileNameName, out value)) 
            {
                return value; 
            } 
            else
            { 
                return string.Empty;
            }
        }
 
        //Whether user can set breakpoint for this type of node.
        static bool DebuggableNode(XamlNode node) 
        { 
            Type t = null;
            switch (node.NodeType) 
            {
                case XamlNodeType.StartObject:
                    XamlStartRecordNode typedRecordNode = node as XamlStartRecordNode;
                    if (typedRecordNode != null && typedRecordNode.RecordType != null) 
                    {
                        t = typedRecordNode.RecordType.UnderlyingType; 
                    } 
                    break;
                case XamlNodeType.EndObject: 
                    XamlEndRecordNode typedEndRecordNode = node as XamlEndRecordNode;
                    if (typedEndRecordNode != null && typedEndRecordNode.RecordType != null)
                    {
                        t = typedEndRecordNode.RecordType.UnderlyingType; 
                    }
                    break; 
                case XamlNodeType.StartMember: 
                    XamlStartMemberNode typedMemberNode = node as XamlStartMemberNode;
                    if (typedMemberNode != null && typedMemberNode.RecordType != null) 
                    {
                        t = typedMemberNode.RecordType.UnderlyingType;
                    }
                    break; 
                case XamlNodeType.EndMember:
                    XamlEndMemberNode typedEndMemberNode = node as XamlEndMemberNode; 
                    if (typedEndMemberNode != null && typedEndMemberNode.RecordType != null) 
                    {
                        t = typedEndMemberNode.RecordType.UnderlyingType; 
                    }
                    break;
            }
 
            bool isDebuggableNode = false;
 
            if (((t != null) && 
                 (typeof(Activity).IsAssignableFrom(t) &&
                    !(typeof(IExpressionContainer).IsAssignableFrom(t) || 
                      typeof(IValueSerializableExpression).IsAssignableFrom(t)))))
            {
                isDebuggableNode = true;
            } 

            return isDebuggableNode; 
        } 

        // Copy source location information from source to destination (if available) 
        public static void CopyAttachedSourceLocation(object source, object destination)
        {
            int startLine, startColumn, endLine, endColumn;
 
            if (AttachablePropertyServices.TryGetProperty(source, StartLineName, out startLine) &&
                AttachablePropertyServices.TryGetProperty(source, StartColumnName, out startColumn) && 
                AttachablePropertyServices.TryGetProperty(source, EndLineName, out endLine) && 
                AttachablePropertyServices.TryGetProperty(source, EndColumnName, out endColumn))
            { 
                SetStartLine(destination, startLine);
                SetStartColumn(destination, startColumn);
                SetEndLine(destination, endLine);
                SetEndColumn(destination, endColumn); 
            }
        } 
 
        [Fx.Tag.InheritThrows(From = "Read", FromDeclaringType = typeof(XamlReader))]
        public override bool Read() 
        {
            this.state.Read(this);
            this.current = this.state.GetCurrent(this);
            return !this.underlyingReader.EndOfInput; 
        }
 
 
        internal void PrepareLineInfo()
        { 
            XamlNode startNode = this.records.Pop();

 	        FilePosition startPosition = new FilePosition(startNode.LineNumber, startNode.LinePosition);
            FilePosition endPosition = new FilePosition(this.Current.LineNumber, this.Current.LinePosition); 

 
            if (this.bracketLocator != null) 
            {
                // Need to make correction for single tag for both start/end xml tag, e.g.  
                // The XamlXmlReader will give the endPosition at the next start tag instead.

                FilePosition previousCloseBracketBeforeEnd = this.bracketLocator.FindCloseBracketBefore(endPosition);
                FilePosition nextOpenBracketAfterStart = this.bracketLocator.FindOpenBracketAfter(startPosition); 
                if (FilePosition.Comparer.Compare(nextOpenBracketAfterStart, previousCloseBracketBeforeEnd) > 0)
                { 
                    // previousCloseBracketBeforeEnd is located *after* nextOpenBracketBeforeStart. 
                    // This is the case where a single tag for both start/end tag.
                    endPosition = previousCloseBracketBeforeEnd; 
                }
                else
                {
                    // General case.  Need to advance the span to the end close bracket (instead of the position 
                    // of "/" at 
                    endPosition = this.bracketLocator.FindCloseBracketAfter(endPosition); 
                } 

                // Now fix the start position. XamlXmlReader did not advance when reading x:Class 
                // in the beginning of activity.
                FilePosition openBracketBeforeStart = this.bracketLocator.FindOpenBracketBefore(startPosition);
                if (openBracketBeforeStart.Line == startPosition.Line &&
                    (openBracketBeforeStart.Column+1) == startPosition.Column)  // OpenBracketBeforeStart is directly preceed the startPosition 
                {   // General case.
                    startPosition = openBracketBeforeStart; 
                } 
                else
                { 
                    // This is when the XamlXmlReader did not advance reading x:Class.
                    // Move startPosition to the nextOpenBracketAfterStart.
                    startPosition = nextOpenBracketAfterStart;
                } 
                endPosition.Column += 1;    // To include the ">" in the span.
            } 
 
            PrepareLineInfo(startPosition, endPosition);
        } 

        void PrepareLineInfo(FilePosition startPosition, FilePosition endPosition)
        {
            this.lineInfoStateStack.Clear(); 
            // Push to stack in reverse order.
            PushToLineInfoStateStack(this.attachingXamlTypeName.GetAttachableMember(EndColumnName.MemberName), endPosition.Column); 
            PushToLineInfoStateStack(this.attachingXamlTypeName.GetAttachableMember(EndLineName.MemberName), endPosition.Line); 
            PushToLineInfoStateStack(this.attachingXamlTypeName.GetAttachableMember(StartColumnName.MemberName), startPosition.Column);
            PushToLineInfoStateStack(this.attachingXamlTypeName.GetAttachableMember(StartLineName.MemberName), startPosition.Line); 
        }

        void PushToLineInfoStateStack(XamlMember member, int value)
        { 
            // Reverse order because it is a stack.
            this.lineInfoStateStack.Push(new XamlEndMemberNode() { Member = member }); 
            this.lineInfoStateStack.Push(new XamlAtomNode() { Value = value }); 
            this.lineInfoStateStack.Push(new XamlStartMemberNode() { Member = member });
        } 

        abstract class ReadState
        {
            public abstract XamlNode GetCurrent(XamlDebuggerXmlReader reader); 

            public abstract void Read(XamlDebuggerXmlReader reader); 
 
            protected bool UnderlyingReaderRead(XamlDebuggerXmlReader reader)
            { 
                bool returnValue = reader.underlyingReader.Read();
                return returnValue;
            }
        } 

        class InReaderState : ReadState 
        { 
            public static readonly InReaderState Instance = new InReaderState();
 
            public override XamlNode GetCurrent(XamlDebuggerXmlReader reader)
            {
                return reader.underlyingReader.Current;
            } 

            public override void Read(XamlDebuggerXmlReader reader) 
            { 
                if (!UnderlyingReaderRead(reader))
                { 
                    reader.current = null;
                    return;
                }
 
                reader.current = reader.underlyingReader.Current;
                if (DebuggableNode(reader.current)) 
                { 
                    switch (reader.Current.NodeType)
                    { 
                        case XamlNodeType.StartObject:
                            reader.records.Push(reader.Current);
                            break;
                        case XamlNodeType.EndObject: 
                            reader.PrepareLineInfo();
                            reader.state = InAttachingLineInfoState.Instance; 
                            break; 
                    }
                } 
            }
        }

        class InAttachingLineInfoState : ReadState 
        {
            public static readonly InAttachingLineInfoState Instance = new InAttachingLineInfoState(); 
 
            public override XamlNode GetCurrent(XamlDebuggerXmlReader reader)
            { 
                Fx.Assert(reader.lineInfoStateStack.Count > 0, "Should not be InAttachingLineInfoState with empty lineInfoStateStack");
                return reader.lineInfoStateStack.Pop();
            }
 
            public override void Read(XamlDebuggerXmlReader reader)
            { 
                if (reader.lineInfoStateStack.Count == 0) 
                {
                    reader.state = InReaderState.Instance; 
                }
            }
        }
 
        class BracketLocator
        { 
            List openBracketPositions; 
            List closeBracketPositions;
 
            public BracketLocator(TextReader reader)
            {
                this.openBracketPositions = new List();
                this.closeBracketPositions = new List(); 
                FilePosition sentinel = new FilePosition(0, 0);
                this.openBracketPositions.Add(sentinel); 
                this.closeBracketPositions.Add(sentinel); 
                string lineString;
                int lineNumber = 1; // Line number and column are 1-based. 
                while ((lineString = reader.ReadLine()) != null)
                {
                    for (int i = 0; i < lineString.Length; ++i)
                    { 
                        if (lineString[i] == '<')
                        { 
                            this.openBracketPositions.Add(new FilePosition(lineNumber, i + 1)); 
                        }
                        else if (lineString[i] == '>') 
                        {
                            this.closeBracketPositions.Add(new FilePosition(lineNumber, i + 1));
                        }
                    } 
                    ++lineNumber;
                } 
                sentinel = new FilePosition(lineNumber, 1); 
                this.openBracketPositions.Add(sentinel);
                this.closeBracketPositions.Add(sentinel); 
            }

            public FilePosition FindOpenBracketBefore(FilePosition position)
            { 
                return GetPositionBefore(this.openBracketPositions, position);
            } 
 
            public FilePosition FindOpenBracketAfter(FilePosition position)
            { 
                return GetPositionAfter(this.openBracketPositions, position);
            }

            public FilePosition FindCloseBracketBefore(FilePosition position) 
            {
                return GetPositionBefore(this.closeBracketPositions, position); 
            } 

            public FilePosition FindCloseBracketAfter(FilePosition position) 
            {
                return GetPositionAfter(this.closeBracketPositions, position);
            }
 

            static FilePosition GetPositionBefore(List positions, FilePosition beforeThis) 
            { 
                int index = positions.BinarySearch(beforeThis, FilePosition.Comparer);
                if (index < 0) 
                {
                    index = ~index;
                }
                Fx.Assert(0 < index && index <= positions.Count, "Invalid index:" + index.ToString(CultureInfo.InvariantCulture)); 
                return positions[index-1];
            } 
 
            static FilePosition GetPositionAfter(List positions, FilePosition afterThis)
            { 
                int index = positions.BinarySearch(afterThis, FilePosition.Comparer);

                if (index < 0)
                { 
                    index = ~index;
                } 
                else 
                {
                    ++index; 
                }
                Fx.Assert(0 <= index && index < positions.Count, "Invalid index: " + index.ToString(CultureInfo.InvariantCulture));
                return positions[index];
            } 
        }
 
        struct FilePosition 
        {
            public FilePosition(int line, int column) 
            {
                this.Line = line;
                this.Column = column;
            } 

            public int Line; 
            public int Column; 
            static public FilePositionComparer Comparer = new FilePositionComparer();
        } 

        class FilePositionComparer : IComparer
        {
            public int Compare(FilePosition x, FilePosition y) 
            {
                if (x.Line == y.Line) 
                { 
                    return x.Column - y.Column;
                } 
                else
                {
                    return x.Line - y.Line;
                } 
            }
        } 
 
    }
 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

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