XamlReader.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / System / Windows / Markup / XamlReader.cs / 1 / XamlReader.cs

                            //---------------------------------------------------------------------------- 
//
// File: XamlReader.cs
//
// Description: 
//   base Parser class that parses XML markup into an Avalon Element Tree
// 
// 
// History:
//    6/06/01:    rogerg        Created as Parser.cs 
//    5/29/03:    peterost      Ported to wcp as Parser.cs
//    8/04/05:    a-neabbu    Split Parser into XamlReader and XamlWriter
//
// Copyright (C) 2003 by Microsoft Corporation.  All rights reserved. 
//
//--------------------------------------------------------------------------- 
using System; 
using System.Xml;
using System.IO; 
using System.IO.Packaging;
using System.Windows;
using System.ComponentModel;
using System.Collections; 
using System.Diagnostics;
using System.Reflection; 
 
using MS.Utility;
using System.Security; 
using System.Security.Permissions;
using System.Security.Policy;
using System.Text;
using System.ComponentModel.Design.Serialization; 
using System.Globalization;
using System.Windows.Markup.Primitives; 
using MS.Internal; 

using MS.Internal.IO.Packaging; 

namespace System.Windows.Markup
{
    ///  
    /// Parsing class used to create an Windows Presentation Platform Tree
    ///  
    public class XamlReader 
    {
#region Public Methods 

        /// 
        /// Reads XAML using the passed xamlText string, building an object tree and returning the
        /// root of that tree. 
        /// 
        /// XAML text as a string 
        /// object root generated after xaml is parsed 
        public static object Parse(string xamlText)
        { 
            StringReader stringReader = new StringReader(xamlText);
            XmlReader xmlReader = XmlReader.Create(stringReader);
            return Load(xmlReader);
        } 

        ///  
        /// Reads XAML using the passed xamlText, building an object tree and returning the 
        /// root of that tree.
        ///  
        /// XAML text as a string
        /// parser context
        /// object root generated after xaml is parsed
        public static object Parse(string xamlText, ParserContext parserContext) 
        {
            Stream xamlStream = new MemoryStream(UTF8Encoding.Default.GetBytes(xamlText)); 
            return Load(xamlStream, parserContext); 
        }
 
        /// 
        /// Reads XAML from the passed stream,building an object tree and returning the
        /// root of that tree.
        ///  
        /// input as stream
        /// object root generated after xml parsed 
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 
        public static object Load(Stream stream)
        { 
            bool etwTracingEnabled = false;
            object root = null;

#if DEBUG_CLR_MEM 
            bool clrTracingEnabled = false;
            // Use local pass variable to correctly log nested parses. 
            int pass = 0; 

            if (CLRProfilerControl.ProcessIsUnderCLRProfiler && 
               (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance))
            {
                clrTracingEnabled = true;
                pass = ++_CLRXamlPass; 
                CLRProfilerControl.CLRLogWriteLine("Begin_XamlParse_{0}", pass);
            } 
#endif // DEBUG_CLR_MEM 

            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal)) 
            {
                etwTracingEnabled = true;
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID),
                                                    MS.Utility.EventType.StartEvent); 
            }
 
            if( TraceMarkup.IsEnabled ) 
            {
                TraceMarkup.Trace( TraceEventType.Start, TraceMarkup.Load ); 
            }

            try
            { 

                if (null == stream) 
                { 
                    throw new ArgumentNullException("stream");
                } 

                ParserContext pc = new ParserContext();

                // Is this really the right thing to do? Can this XamlTypeMapper be reused? 
                if (null == pc.XamlTypeMapper)
                { 
                    pc.XamlTypeMapper = XmlParserDefaults.DefaultMapper; 
                }
 
                // In some cases, the application constructor is not run prior to loading,
                // causing the loader not to recognize URIs beginning with “pack:” or “application:”.

                System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(System.Windows.Application).TypeHandle); 

                root = XmlTreeBuildDefault(pc, stream, XamlParseMode.Synchronous, etwTracingEnabled); 
            } 

            finally 
            {

                if( TraceMarkup.IsEnabled )
                { 
                    TraceMarkup.Trace( TraceEventType.Stop, TraceMarkup.Load, root );
                } 
 
                if (etwTracingEnabled)
                { 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID), MS.Utility.EventType.EndEvent);
                }

#if DEBUG_CLR_MEM 
                if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance))
                { 
                    CLRProfilerControl.CLRLogWriteLine("End_XamlParse_{0}", pass); 
                }
#endif // DEBUG_CLR_MEM 
            }

            return (root);
        } 

        ///  
        /// Reads XAML using the passed XmlReader, building an object tree and returning the 
        /// root of that tree.
        ///  
        /// Reader of xml content.
        /// object root generated after xml parsed
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647
        public static object Load( 
            XmlReader    reader)
        { 
            bool etwTracingEnabled = false; 
            object root = null;
 
#if DEBUG_CLR_MEM
            bool clrTracingEnabled = false;
            // Use local pass variable to correctly log nested parses.
            int pass = 0; 

            if (CLRProfilerControl.ProcessIsUnderCLRProfiler && 
               (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) 
            {
                clrTracingEnabled = true; 
                pass = ++_CLRXamlPass;
                CLRProfilerControl.CLRLogWriteLine("Begin_XamlParse_{0}", pass);
            }
#endif // DEBUG_CLR_MEM 

            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal)) 
            { 
                etwTracingEnabled = true;
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID), MS.Utility.EventType.StartEvent); 
            }

            if( TraceMarkup.IsEnabled )
            { 
                TraceMarkup.Trace( TraceEventType.Start, TraceMarkup.Load );
            } 
 
            try
            { 
                if (null == reader)
                {
                    throw new ArgumentNullException("reader");
                } 

                // Create the parser context, pulling existing XML context from the 
                // XmlReader (Lang, Space, and BaseURI). 
                ParserContext pc = new ParserContext( reader );
 
                // Is this really the right thing to do? Can this XamlTypeMapper be reused?
                if (null == pc.XamlTypeMapper)
                {
                    pc.XamlTypeMapper = XmlParserDefaults.DefaultMapper; 
                }
 
                root = XmlTreeBuildDefault(pc, reader, true, XamlParseMode.Synchronous, etwTracingEnabled); 

            } 

            finally
            {
                if( TraceMarkup.IsEnabled ) 
                {
                    TraceMarkup.Trace( TraceEventType.Stop, TraceMarkup.Load, root ); 
                } 

                if (etwTracingEnabled) 
                {
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID), MS.Utility.EventType.EndEvent);
                }
 
#if DEBUG_CLR_MEM
                if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) 
                { 
                    CLRProfilerControl.CLRLogWriteLine("End_XamlParse_{0}", pass);
                } 
#endif // DEBUG_CLR_MEM
            }

            return (root); 
        }
 
        ///  
        /// Reads XAML from the passed stream, building an object tree and returning the
        /// root of that tree. 
        /// 
        /// input as stream
        /// parser context
        /// object root generated after xml parsed 
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647
        public static object Load( 
            Stream stream, 
            ParserContext parserContext)
        { 
            bool etwTracingEnabled = false;
            object root = null;

#if DEBUG_CLR_MEM 
            bool clrTracingEnabled = false;
            // Use local pass variable to correctly log nested parses. 
            int pass = 0; 

            if (CLRProfilerControl.ProcessIsUnderCLRProfiler && 
               (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance))
            {
                clrTracingEnabled = true;
                pass = ++_CLRXamlPass; 
                CLRProfilerControl.CLRLogWriteLine("Begin_XamlParse_{0}", pass);
            } 
#endif // DEBUG_CLR_MEM 

            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal)) 
            {
                etwTracingEnabled = true;
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID), MS.Utility.EventType.StartEvent);
            } 

            if( TraceMarkup.IsEnabled ) 
            { 
                TraceMarkup.Trace( TraceEventType.Start, TraceMarkup.Load );
            } 

            try
            {
                if (null == stream) 
                {
                    throw new ArgumentNullException("stream"); 
                } 

                if (null == parserContext) 
                {
                    throw new ArgumentNullException("parserContext");
                }
 
                // Is this really the right thing to do? Can this XamlTypeMapper be reused?
                if (null == parserContext.XamlTypeMapper) 
                { 
                    parserContext.XamlTypeMapper = XmlParserDefaults.DefaultMapper;
                } 

                root = XmlTreeBuildDefault(parserContext, stream, XamlParseMode.Synchronous, etwTracingEnabled);
            }
 
            finally
            { 
                if( TraceMarkup.IsEnabled ) 
                {
                    TraceMarkup.Trace( TraceEventType.Stop, TraceMarkup.Load, root ); 
                }

                if (etwTracingEnabled)
                { 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID), MS.Utility.EventType.EndEvent);
                } 
 
#if DEBUG_CLR_MEM
                if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) 
                {
                    CLRProfilerControl.CLRLogWriteLine("End_XamlParse_{0}", pass);
                }
#endif // DEBUG_CLR_MEM 
            }
 
            return (root); 
        }
 

        /// 
        /// Loads XAML from the given stream, building an object tree.
        /// The load operation will be done asynchronously if the 
        /// markup specifies x:SynchronousMode="async".
        ///  
        /// stream for the xml content 
        /// object root generated after xml parsed
        ///  
        /// Notice that this is an instance method
        /// 
        public object LoadAsync(Stream stream)
        { 
            if (null == stream)
            { 
                throw new ArgumentNullException("stream"); 
            }
 
            if (_treeBuilder != null)
            {
                // A XamlReader instance cannot be shared across two load operations
                throw new InvalidOperationException(SR.Get(SRID.ParserCannotReuseXamlReader)); 
            }
 
            ParserContext parserContext = new ParserContext(); 
            parserContext.XamlTypeMapper = XmlParserDefaults.DefaultMapper;
 
            _treeBuilder = new XamlTreeBuilder(parserContext, stream, XamlParseMode.Uninitialized);
            _treeBuilder.ParseCompleted += new EventHandler(OnLoadCompleted);
            return _treeBuilder.Parse();
        } 

        ///  
        /// Reads XAML using the given XmlReader, building an object tree. 
        /// The load operation will be done asynchronously if the markup
        /// specifies x:SynchronousMode="async". 
        /// 
        /// Reader for xml content.
        /// object root generated after xml parsed
        ///  
        /// Notice that this is an instance method
        ///  
        public object LoadAsync(XmlReader reader) 
        {
            if (null == reader) 
            {
                throw new ArgumentNullException("reader");
            }
 
            if (_treeBuilder != null)
            { 
                // A XamlReader instance cannot be shared across two load operations 
                throw new InvalidOperationException(SR.Get(SRID.ParserCannotReuseXamlReader));
            } 

            ParserContext parserContext = new ParserContext(reader);
            parserContext.XamlTypeMapper = XmlParserDefaults.DefaultMapper;
 
            _treeBuilder = new XamlTreeBuilder(parserContext, reader, true, XamlParseMode.Uninitialized);
            _treeBuilder.ParseCompleted += new EventHandler(OnLoadCompleted); 
            return _treeBuilder.Parse(); 
        }
 
        /// 
        /// Loads XAML from the given stream, building an object tree.
        /// The load operation will be done asynchronously if the
        /// markup specifies x:SynchronousMode="async". 
        /// 
        /// stream for the xml content 
        /// parser context 
        /// object root generated after xml parsed
        ///  
        /// Notice that this is an instance method
        /// 
        public object LoadAsync(Stream stream, ParserContext parserContext)
        { 
            if (null == stream)
            { 
                throw new ArgumentNullException("stream"); 
            }
 
            if (_treeBuilder != null)
            {
                // A XamlReader instance cannot be shared across two load operations
                throw new InvalidOperationException(SR.Get(SRID.ParserCannotReuseXamlReader)); 
            }
 
            if (parserContext == null) 
            {
                parserContext = new ParserContext(); 
            }

            if (null == parserContext.XamlTypeMapper)
            { 
                parserContext.XamlTypeMapper = XmlParserDefaults.DefaultMapper;
            } 
 
            _treeBuilder = new XamlTreeBuilder(parserContext, stream, XamlParseMode.Uninitialized);
            _treeBuilder.ParseCompleted += new EventHandler(OnLoadCompleted); 
            return _treeBuilder.Parse();
        }

        ///  
        /// Aborts the current async load operation if there is one.
        ///  
        ///  
        /// Notice that the cancellation is an asynchronous operation in itself which means
        /// that there may be some amount of loading that happens before the operation 
        /// actually gets aborted.
        /// 
        public void CancelAsync()
        { 
            if (null != _treeBuilder)
            { 
                _treeBuilder.XamlTreeBuildCancel(); 
            }
        } 

        /// 
        /// This event is fired when either a [....] or an async load operation has completed
        /// or when an async load operation is aborted. 
        /// 
        public event AsyncCompletedEventHandler LoadCompleted; 
 
#endregion Public Methods
 
#region Internal Methods

        /// 
        /// This is the event listener for the ParseCompleted event on XamlTreeBuidler 
        /// 
        private void OnLoadCompleted(object sender, EventArgs args) 
        { 
            // Fire the LoadCompleted event listeners
            if (LoadCompleted != null) 
            {
                LoadCompleted(this, new AsyncCompletedEventArgs(_treeBuilder.ParseException, _treeBuilder.ParseCancelled, null /*userState*/));
            }
 
            // Clear the _treeBuilder
            _treeBuilder.ParseCompleted -= new EventHandler(OnLoadCompleted); 
            _treeBuilder = null; 
        }
 
        /// 
        /// Reads XAML from the passed stream, building an object tree and returning the
        /// root of that tree.  Wrap a CompatibilityReader with another XmlReader that
        /// uses the passed reader settings to allow validation of xaml. 
        /// 
        /// XmlReader to use.  This is NOT wrapped by any 
        ///  other reader 
        /// Optional parser context.  May be null 
        /// Sets synchronous or asynchronous parsing 
        /// object root generated after xml parsed
        // Note this is the internal entry point for XPS.  XPS calls here so
        // its reader is not wrapped with a Markup Compat Reader.
        internal static object Load( 
            XmlReader     reader,
            ParserContext context, 
            XamlParseMode parseMode) 
        {
            bool etwTracingEnabled = false; 
            object root = null;

#if DEBUG_CLR_MEM
            bool clrTracingEnabled = false; 
            // Use local pass variable to correctly log nested parses.
            int pass = 0; 
 
            if (CLRProfilerControl.ProcessIsUnderCLRProfiler &&
               (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) 
            {
                clrTracingEnabled = true;
                pass = ++_CLRXamlPass;
                CLRProfilerControl.CLRLogWriteLine("Begin_XamlParse_{0}", pass); 
            }
#endif // DEBUG_CLR_MEM 
 
            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal))
            { 
                etwTracingEnabled = true;
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID), MS.Utility.EventType.StartEvent);
            }
 
            if( TraceMarkup.IsEnabled )
            { 
                TraceMarkup.Trace( TraceEventType.Start, TraceMarkup.Load ); 
            }
 
            try
            {
                if (null == reader)
                { 
                    throw new ArgumentNullException("reader");
                } 
 
                if (context == null)
                { 
                    context = new ParserContext();
                }

                // Is this really the right thing to do? Can this XamlTypeMapper be reused? 
                if (null == context.XamlTypeMapper)
                { 
                    context.XamlTypeMapper = XmlParserDefaults.DefaultMapper; 
                }
 
                root = XmlTreeBuildDefault(context, reader, false, parseMode, etwTracingEnabled);
            }

            finally 
            {
                if( TraceMarkup.IsEnabled ) 
                { 
                    TraceMarkup.Trace( TraceEventType.Stop, TraceMarkup.Load, root );
                } 

                if (etwTracingEnabled)
                {
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID), MS.Utility.EventType.EndEvent); 
                }
 
#if DEBUG_CLR_MEM 
                if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance))
                { 
                    CLRProfilerControl.CLRLogWriteLine("End_XamlParse_{0}", pass);
                }
#endif // DEBUG_CLR_MEM
            } 

            return (root); 
        } 

        ///  
        /// Reads XAML from the passed stream, building an object tree and returning the
        /// root of that tree.
        /// 
        /// input as stream 
        /// hooks to callback during load
        /// parser context 
        /// object root generated after xml parsed 
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647
        // 


        internal static object Load(
            Stream        stream, 
            ParserHooks   hooks,
            ParserContext parserContext) 
        { 
            bool etwTracingEnabled = false;
            object root = null; 

#if DEBUG_CLR_MEM
            bool clrTracingEnabled = false;
            // Use local pass variable to correctly log nested parses. 
            int pass = 0;
 
            if (CLRProfilerControl.ProcessIsUnderCLRProfiler && 
               (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance))
            { 
                clrTracingEnabled = true;
                pass = ++_CLRXamlPass;
                CLRProfilerControl.CLRLogWriteLine("Begin_XamlParse_{0}", pass);
            } 
#endif // DEBUG_CLR_MEM
 
            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal)) 
            {
                etwTracingEnabled = true; 
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID), MS.Utility.EventType.StartEvent);
            }

            if( TraceMarkup.IsEnabled ) 
            {
                TraceMarkup.Trace( TraceEventType.Start, TraceMarkup.Load ); 
            } 

            try 
            {
                if (null == stream)
                {
                    throw new ArgumentNullException("stream"); 
                }
 
                if (null == parserContext) 
                {
                    throw new ArgumentNullException("parserContext"); 
                }

                // Is this really the right thing to do? Can this XamlTypeMapper be reused?
                if (null == parserContext.XamlTypeMapper) 
                {
                    parserContext.XamlTypeMapper = XmlParserDefaults.DefaultMapper; 
                } 

                root = XmlTreeBuildAssembly(parserContext, stream, hooks, etwTracingEnabled); 
            }

            finally
            { 
                if( TraceMarkup.IsEnabled )
                { 
                    TraceMarkup.Trace( TraceEventType.Stop, TraceMarkup.Load, root ); 
                }
 
                if (etwTracingEnabled)
                {
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID), MS.Utility.EventType.EndEvent);
                } 

#if DEBUG_CLR_MEM 
                if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) 
                {
                    CLRProfilerControl.CLRLogWriteLine("End_XamlParse_{0}", pass); 
                }
#endif // DEBUG_CLR_MEM
            }
 
            return (root);
        } 
 
        /// 
        /// Loads the given baml stream 
        /// 
        /// input as stream
        /// parent owner element of baml tree
        /// parser context 
        /// True if stream should be closed by the
        ///    parser after parsing is complete.  False if the stream should be left open 
        /// object root generated after baml parsed 
        /// 
        ///     Critical - because it sets _streamCreatedAssembly on the ParserContext, and that is 
        ///                SecurityCritical Data as this field is used by the BamlRecordReader to
        ///                allow legitimate internal types in Partial Trust.
        ///     Safe - because it gets this value from the stream if it implements an internal IStreamInfo
        ///            interface and IStreamInfo.Assembly is set by the ResourceContainer code that is 
        ///            SecurityCritical, but treated as safe.
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647
        internal static object LoadBaml( 
            Stream stream,
            ParserContext parserContext,
            object parent,
            bool closeStream) 
        {
            Debug.Assert(stream != null && parserContext != null); 
 
            bool etwTracingEnabled = false;
            object root = null; 

#if DEBUG_CLR_MEM
            bool clrTracingEnabled = false;
            // Use local pass variable to correctly log nested parses. 
            int pass = 0;
 
            if (CLRProfilerControl.ProcessIsUnderCLRProfiler && 
               (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance))
            { 
                clrTracingEnabled = true;
                pass = ++_CLRBamlPass;
                CLRProfilerControl.CLRLogWriteLine("Begin_BamlParse_{0}", pass);
            } 
#endif // DEBUG_CLR_MEM
 
            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal)) 
            {
                etwTracingEnabled = true; 
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEBAMLGUID), MS.Utility.EventType.StartEvent);
            }

            if( TraceMarkup.IsEnabled ) 
            {
                TraceMarkup.Trace( TraceEventType.Start, TraceMarkup.Load ); 
            } 

            try 
            {
                if (null == parserContext.XamlTypeMapper)
                {
                    parserContext.XamlTypeMapper = XmlParserDefaults.DefaultMapper; 
                }
 
                // 
                // If the stream contains info about the Assembly that created it,
                // set StreamCreatedAssembly from the stream instance. 
                //
                IStreamInfo streamInfo = stream as IStreamInfo;
                if (streamInfo != null)
                { 
                    parserContext.StreamCreatedAssembly = streamInfo.Assembly;
                } 
 
                TreeBuilderBamlTranslator treeBuilder = new TreeBuilderBamlTranslator(stream, parserContext, parent, closeStream);
 
                root = treeBuilder.Parse();

                Debug.Assert(parent == null || root == parent);
            } 

            finally 
            { 
                if( TraceMarkup.IsEnabled )
                { 
                    TraceMarkup.Trace( TraceEventType.Stop, TraceMarkup.Load, root );
                }

                if (etwTracingEnabled) 
                {
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEBAMLGUID), MS.Utility.EventType.EndEvent); 
                } 

#if DEBUG_CLR_MEM 
                if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance))
                {
                    CLRProfilerControl.CLRLogWriteLine("End_BamlParse_{0}", pass);
                } 
#endif // DEBUG_CLR_MEM
            } 
 
            return (root);
        } 

#endregion Internal Methods

#region Private Methods 
        /// 
        /// Reads XAML from the passed stream, building an object tree and returning the 
        /// root of that tree.  This override is used to pass settings used for validation. 
        /// 
        /// ParserContext 
        /// XmlReader
        /// Should wrap 'reader' with an XML Compatibility Reader
        /// Sets synchronous or asynchronous parsing
        /// input as bool 
        /// object root generated after xml parsed
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 
        private static object XmlTreeBuildDefault( 
            ParserContext pc,
            XmlReader     reader, 
            bool          wrapWithMarkupCompatReader,
            XamlParseMode parseMode,
            bool          etwTracingEnabled)
        { 
            XamlTreeBuilder treeBuilder = new XamlTreeBuilder(pc, reader, wrapWithMarkupCompatReader, parseMode);
 
            if (etwTracingEnabled) 
            {
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLINITIALIZEDGUID), MS.Utility.EventType.Info); 
            }

            object root = treeBuilder.Parse();
 
            return root;
        } 
 
        /// 
        /// Reads XAML from the passed stream, building an object tree and returning the 
        /// root of that tree.
        /// 
        /// ParserContext
        /// input as stream 
        /// Sets synchronous or asynchronous parsing
        /// input as bool 
        /// object root generated after xml parsed 
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647
        private static object XmlTreeBuildDefault( 
            ParserContext pc,
            Stream        stream,
            XamlParseMode parseMode,
            bool          etwTracingEnabled) 
        {
            XamlTreeBuilder treeBuilder = new XamlTreeBuilder(pc, stream, parseMode); 
 
            if (etwTracingEnabled)
            { 
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLINITIALIZEDGUID), MS.Utility.EventType.Info);
            }

            object root = treeBuilder.Parse(); 

            return root; 
        } 

        ///  
        /// Reads XAML from the passed stream, building an object tree and returning the
        /// root of that tree.
        /// 
        /// ParserContext 
        /// input as Stream
        /// hooks to callback during load 
        /// input as bool 
        /// object root generated after xml parsed
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 
        private static object XmlTreeBuildAssembly(
            ParserContext pc,
            Stream        stream,
            ParserHooks   hooks, 
            bool          etwTracingEnabled)
        { 
            // When we have ParserHooks we need to load synchronously 
            XamlTreeBuilder treeBuilder = new XamlTreeBuilder(pc, stream, XamlParseMode.Synchronous);
 
            treeBuilder.ParserHooks = hooks;

            if (etwTracingEnabled)
            { 
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLINITIALIZEDGUID), MS.Utility.EventType.Info);
            } 
 
            object root = treeBuilder.Parse();
 
            return root;
        }
#endregion PrivateMethods
 
#region Data
 
        private XamlTreeBuilder _treeBuilder; 

#if DEBUG_CLR_MEM 
        private static int _CLRBamlPass = 0;
        private static int _CLRXamlPass = 0;
#endif
 
#endregion Data
    } 
} 

 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------------------- 
//
// File: XamlReader.cs
//
// Description: 
//   base Parser class that parses XML markup into an Avalon Element Tree
// 
// 
// History:
//    6/06/01:    rogerg        Created as Parser.cs 
//    5/29/03:    peterost      Ported to wcp as Parser.cs
//    8/04/05:    a-neabbu    Split Parser into XamlReader and XamlWriter
//
// Copyright (C) 2003 by Microsoft Corporation.  All rights reserved. 
//
//--------------------------------------------------------------------------- 
using System; 
using System.Xml;
using System.IO; 
using System.IO.Packaging;
using System.Windows;
using System.ComponentModel;
using System.Collections; 
using System.Diagnostics;
using System.Reflection; 
 
using MS.Utility;
using System.Security; 
using System.Security.Permissions;
using System.Security.Policy;
using System.Text;
using System.ComponentModel.Design.Serialization; 
using System.Globalization;
using System.Windows.Markup.Primitives; 
using MS.Internal; 

using MS.Internal.IO.Packaging; 

namespace System.Windows.Markup
{
    ///  
    /// Parsing class used to create an Windows Presentation Platform Tree
    ///  
    public class XamlReader 
    {
#region Public Methods 

        /// 
        /// Reads XAML using the passed xamlText string, building an object tree and returning the
        /// root of that tree. 
        /// 
        /// XAML text as a string 
        /// object root generated after xaml is parsed 
        public static object Parse(string xamlText)
        { 
            StringReader stringReader = new StringReader(xamlText);
            XmlReader xmlReader = XmlReader.Create(stringReader);
            return Load(xmlReader);
        } 

        ///  
        /// Reads XAML using the passed xamlText, building an object tree and returning the 
        /// root of that tree.
        ///  
        /// XAML text as a string
        /// parser context
        /// object root generated after xaml is parsed
        public static object Parse(string xamlText, ParserContext parserContext) 
        {
            Stream xamlStream = new MemoryStream(UTF8Encoding.Default.GetBytes(xamlText)); 
            return Load(xamlStream, parserContext); 
        }
 
        /// 
        /// Reads XAML from the passed stream,building an object tree and returning the
        /// root of that tree.
        ///  
        /// input as stream
        /// object root generated after xml parsed 
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 
        public static object Load(Stream stream)
        { 
            bool etwTracingEnabled = false;
            object root = null;

#if DEBUG_CLR_MEM 
            bool clrTracingEnabled = false;
            // Use local pass variable to correctly log nested parses. 
            int pass = 0; 

            if (CLRProfilerControl.ProcessIsUnderCLRProfiler && 
               (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance))
            {
                clrTracingEnabled = true;
                pass = ++_CLRXamlPass; 
                CLRProfilerControl.CLRLogWriteLine("Begin_XamlParse_{0}", pass);
            } 
#endif // DEBUG_CLR_MEM 

            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal)) 
            {
                etwTracingEnabled = true;
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID),
                                                    MS.Utility.EventType.StartEvent); 
            }
 
            if( TraceMarkup.IsEnabled ) 
            {
                TraceMarkup.Trace( TraceEventType.Start, TraceMarkup.Load ); 
            }

            try
            { 

                if (null == stream) 
                { 
                    throw new ArgumentNullException("stream");
                } 

                ParserContext pc = new ParserContext();

                // Is this really the right thing to do? Can this XamlTypeMapper be reused? 
                if (null == pc.XamlTypeMapper)
                { 
                    pc.XamlTypeMapper = XmlParserDefaults.DefaultMapper; 
                }
 
                // In some cases, the application constructor is not run prior to loading,
                // causing the loader not to recognize URIs beginning with “pack:” or “application:”.

                System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(System.Windows.Application).TypeHandle); 

                root = XmlTreeBuildDefault(pc, stream, XamlParseMode.Synchronous, etwTracingEnabled); 
            } 

            finally 
            {

                if( TraceMarkup.IsEnabled )
                { 
                    TraceMarkup.Trace( TraceEventType.Stop, TraceMarkup.Load, root );
                } 
 
                if (etwTracingEnabled)
                { 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID), MS.Utility.EventType.EndEvent);
                }

#if DEBUG_CLR_MEM 
                if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance))
                { 
                    CLRProfilerControl.CLRLogWriteLine("End_XamlParse_{0}", pass); 
                }
#endif // DEBUG_CLR_MEM 
            }

            return (root);
        } 

        ///  
        /// Reads XAML using the passed XmlReader, building an object tree and returning the 
        /// root of that tree.
        ///  
        /// Reader of xml content.
        /// object root generated after xml parsed
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647
        public static object Load( 
            XmlReader    reader)
        { 
            bool etwTracingEnabled = false; 
            object root = null;
 
#if DEBUG_CLR_MEM
            bool clrTracingEnabled = false;
            // Use local pass variable to correctly log nested parses.
            int pass = 0; 

            if (CLRProfilerControl.ProcessIsUnderCLRProfiler && 
               (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) 
            {
                clrTracingEnabled = true; 
                pass = ++_CLRXamlPass;
                CLRProfilerControl.CLRLogWriteLine("Begin_XamlParse_{0}", pass);
            }
#endif // DEBUG_CLR_MEM 

            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal)) 
            { 
                etwTracingEnabled = true;
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID), MS.Utility.EventType.StartEvent); 
            }

            if( TraceMarkup.IsEnabled )
            { 
                TraceMarkup.Trace( TraceEventType.Start, TraceMarkup.Load );
            } 
 
            try
            { 
                if (null == reader)
                {
                    throw new ArgumentNullException("reader");
                } 

                // Create the parser context, pulling existing XML context from the 
                // XmlReader (Lang, Space, and BaseURI). 
                ParserContext pc = new ParserContext( reader );
 
                // Is this really the right thing to do? Can this XamlTypeMapper be reused?
                if (null == pc.XamlTypeMapper)
                {
                    pc.XamlTypeMapper = XmlParserDefaults.DefaultMapper; 
                }
 
                root = XmlTreeBuildDefault(pc, reader, true, XamlParseMode.Synchronous, etwTracingEnabled); 

            } 

            finally
            {
                if( TraceMarkup.IsEnabled ) 
                {
                    TraceMarkup.Trace( TraceEventType.Stop, TraceMarkup.Load, root ); 
                } 

                if (etwTracingEnabled) 
                {
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID), MS.Utility.EventType.EndEvent);
                }
 
#if DEBUG_CLR_MEM
                if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) 
                { 
                    CLRProfilerControl.CLRLogWriteLine("End_XamlParse_{0}", pass);
                } 
#endif // DEBUG_CLR_MEM
            }

            return (root); 
        }
 
        ///  
        /// Reads XAML from the passed stream, building an object tree and returning the
        /// root of that tree. 
        /// 
        /// input as stream
        /// parser context
        /// object root generated after xml parsed 
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647
        public static object Load( 
            Stream stream, 
            ParserContext parserContext)
        { 
            bool etwTracingEnabled = false;
            object root = null;

#if DEBUG_CLR_MEM 
            bool clrTracingEnabled = false;
            // Use local pass variable to correctly log nested parses. 
            int pass = 0; 

            if (CLRProfilerControl.ProcessIsUnderCLRProfiler && 
               (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance))
            {
                clrTracingEnabled = true;
                pass = ++_CLRXamlPass; 
                CLRProfilerControl.CLRLogWriteLine("Begin_XamlParse_{0}", pass);
            } 
#endif // DEBUG_CLR_MEM 

            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal)) 
            {
                etwTracingEnabled = true;
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID), MS.Utility.EventType.StartEvent);
            } 

            if( TraceMarkup.IsEnabled ) 
            { 
                TraceMarkup.Trace( TraceEventType.Start, TraceMarkup.Load );
            } 

            try
            {
                if (null == stream) 
                {
                    throw new ArgumentNullException("stream"); 
                } 

                if (null == parserContext) 
                {
                    throw new ArgumentNullException("parserContext");
                }
 
                // Is this really the right thing to do? Can this XamlTypeMapper be reused?
                if (null == parserContext.XamlTypeMapper) 
                { 
                    parserContext.XamlTypeMapper = XmlParserDefaults.DefaultMapper;
                } 

                root = XmlTreeBuildDefault(parserContext, stream, XamlParseMode.Synchronous, etwTracingEnabled);
            }
 
            finally
            { 
                if( TraceMarkup.IsEnabled ) 
                {
                    TraceMarkup.Trace( TraceEventType.Stop, TraceMarkup.Load, root ); 
                }

                if (etwTracingEnabled)
                { 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID), MS.Utility.EventType.EndEvent);
                } 
 
#if DEBUG_CLR_MEM
                if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) 
                {
                    CLRProfilerControl.CLRLogWriteLine("End_XamlParse_{0}", pass);
                }
#endif // DEBUG_CLR_MEM 
            }
 
            return (root); 
        }
 

        /// 
        /// Loads XAML from the given stream, building an object tree.
        /// The load operation will be done asynchronously if the 
        /// markup specifies x:SynchronousMode="async".
        ///  
        /// stream for the xml content 
        /// object root generated after xml parsed
        ///  
        /// Notice that this is an instance method
        /// 
        public object LoadAsync(Stream stream)
        { 
            if (null == stream)
            { 
                throw new ArgumentNullException("stream"); 
            }
 
            if (_treeBuilder != null)
            {
                // A XamlReader instance cannot be shared across two load operations
                throw new InvalidOperationException(SR.Get(SRID.ParserCannotReuseXamlReader)); 
            }
 
            ParserContext parserContext = new ParserContext(); 
            parserContext.XamlTypeMapper = XmlParserDefaults.DefaultMapper;
 
            _treeBuilder = new XamlTreeBuilder(parserContext, stream, XamlParseMode.Uninitialized);
            _treeBuilder.ParseCompleted += new EventHandler(OnLoadCompleted);
            return _treeBuilder.Parse();
        } 

        ///  
        /// Reads XAML using the given XmlReader, building an object tree. 
        /// The load operation will be done asynchronously if the markup
        /// specifies x:SynchronousMode="async". 
        /// 
        /// Reader for xml content.
        /// object root generated after xml parsed
        ///  
        /// Notice that this is an instance method
        ///  
        public object LoadAsync(XmlReader reader) 
        {
            if (null == reader) 
            {
                throw new ArgumentNullException("reader");
            }
 
            if (_treeBuilder != null)
            { 
                // A XamlReader instance cannot be shared across two load operations 
                throw new InvalidOperationException(SR.Get(SRID.ParserCannotReuseXamlReader));
            } 

            ParserContext parserContext = new ParserContext(reader);
            parserContext.XamlTypeMapper = XmlParserDefaults.DefaultMapper;
 
            _treeBuilder = new XamlTreeBuilder(parserContext, reader, true, XamlParseMode.Uninitialized);
            _treeBuilder.ParseCompleted += new EventHandler(OnLoadCompleted); 
            return _treeBuilder.Parse(); 
        }
 
        /// 
        /// Loads XAML from the given stream, building an object tree.
        /// The load operation will be done asynchronously if the
        /// markup specifies x:SynchronousMode="async". 
        /// 
        /// stream for the xml content 
        /// parser context 
        /// object root generated after xml parsed
        ///  
        /// Notice that this is an instance method
        /// 
        public object LoadAsync(Stream stream, ParserContext parserContext)
        { 
            if (null == stream)
            { 
                throw new ArgumentNullException("stream"); 
            }
 
            if (_treeBuilder != null)
            {
                // A XamlReader instance cannot be shared across two load operations
                throw new InvalidOperationException(SR.Get(SRID.ParserCannotReuseXamlReader)); 
            }
 
            if (parserContext == null) 
            {
                parserContext = new ParserContext(); 
            }

            if (null == parserContext.XamlTypeMapper)
            { 
                parserContext.XamlTypeMapper = XmlParserDefaults.DefaultMapper;
            } 
 
            _treeBuilder = new XamlTreeBuilder(parserContext, stream, XamlParseMode.Uninitialized);
            _treeBuilder.ParseCompleted += new EventHandler(OnLoadCompleted); 
            return _treeBuilder.Parse();
        }

        ///  
        /// Aborts the current async load operation if there is one.
        ///  
        ///  
        /// Notice that the cancellation is an asynchronous operation in itself which means
        /// that there may be some amount of loading that happens before the operation 
        /// actually gets aborted.
        /// 
        public void CancelAsync()
        { 
            if (null != _treeBuilder)
            { 
                _treeBuilder.XamlTreeBuildCancel(); 
            }
        } 

        /// 
        /// This event is fired when either a [....] or an async load operation has completed
        /// or when an async load operation is aborted. 
        /// 
        public event AsyncCompletedEventHandler LoadCompleted; 
 
#endregion Public Methods
 
#region Internal Methods

        /// 
        /// This is the event listener for the ParseCompleted event on XamlTreeBuidler 
        /// 
        private void OnLoadCompleted(object sender, EventArgs args) 
        { 
            // Fire the LoadCompleted event listeners
            if (LoadCompleted != null) 
            {
                LoadCompleted(this, new AsyncCompletedEventArgs(_treeBuilder.ParseException, _treeBuilder.ParseCancelled, null /*userState*/));
            }
 
            // Clear the _treeBuilder
            _treeBuilder.ParseCompleted -= new EventHandler(OnLoadCompleted); 
            _treeBuilder = null; 
        }
 
        /// 
        /// Reads XAML from the passed stream, building an object tree and returning the
        /// root of that tree.  Wrap a CompatibilityReader with another XmlReader that
        /// uses the passed reader settings to allow validation of xaml. 
        /// 
        /// XmlReader to use.  This is NOT wrapped by any 
        ///  other reader 
        /// Optional parser context.  May be null 
        /// Sets synchronous or asynchronous parsing 
        /// object root generated after xml parsed
        // Note this is the internal entry point for XPS.  XPS calls here so
        // its reader is not wrapped with a Markup Compat Reader.
        internal static object Load( 
            XmlReader     reader,
            ParserContext context, 
            XamlParseMode parseMode) 
        {
            bool etwTracingEnabled = false; 
            object root = null;

#if DEBUG_CLR_MEM
            bool clrTracingEnabled = false; 
            // Use local pass variable to correctly log nested parses.
            int pass = 0; 
 
            if (CLRProfilerControl.ProcessIsUnderCLRProfiler &&
               (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) 
            {
                clrTracingEnabled = true;
                pass = ++_CLRXamlPass;
                CLRProfilerControl.CLRLogWriteLine("Begin_XamlParse_{0}", pass); 
            }
#endif // DEBUG_CLR_MEM 
 
            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal))
            { 
                etwTracingEnabled = true;
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID), MS.Utility.EventType.StartEvent);
            }
 
            if( TraceMarkup.IsEnabled )
            { 
                TraceMarkup.Trace( TraceEventType.Start, TraceMarkup.Load ); 
            }
 
            try
            {
                if (null == reader)
                { 
                    throw new ArgumentNullException("reader");
                } 
 
                if (context == null)
                { 
                    context = new ParserContext();
                }

                // Is this really the right thing to do? Can this XamlTypeMapper be reused? 
                if (null == context.XamlTypeMapper)
                { 
                    context.XamlTypeMapper = XmlParserDefaults.DefaultMapper; 
                }
 
                root = XmlTreeBuildDefault(context, reader, false, parseMode, etwTracingEnabled);
            }

            finally 
            {
                if( TraceMarkup.IsEnabled ) 
                { 
                    TraceMarkup.Trace( TraceEventType.Stop, TraceMarkup.Load, root );
                } 

                if (etwTracingEnabled)
                {
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID), MS.Utility.EventType.EndEvent); 
                }
 
#if DEBUG_CLR_MEM 
                if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance))
                { 
                    CLRProfilerControl.CLRLogWriteLine("End_XamlParse_{0}", pass);
                }
#endif // DEBUG_CLR_MEM
            } 

            return (root); 
        } 

        ///  
        /// Reads XAML from the passed stream, building an object tree and returning the
        /// root of that tree.
        /// 
        /// input as stream 
        /// hooks to callback during load
        /// parser context 
        /// object root generated after xml parsed 
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647
        // 


        internal static object Load(
            Stream        stream, 
            ParserHooks   hooks,
            ParserContext parserContext) 
        { 
            bool etwTracingEnabled = false;
            object root = null; 

#if DEBUG_CLR_MEM
            bool clrTracingEnabled = false;
            // Use local pass variable to correctly log nested parses. 
            int pass = 0;
 
            if (CLRProfilerControl.ProcessIsUnderCLRProfiler && 
               (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance))
            { 
                clrTracingEnabled = true;
                pass = ++_CLRXamlPass;
                CLRProfilerControl.CLRLogWriteLine("Begin_XamlParse_{0}", pass);
            } 
#endif // DEBUG_CLR_MEM
 
            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal)) 
            {
                etwTracingEnabled = true; 
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID), MS.Utility.EventType.StartEvent);
            }

            if( TraceMarkup.IsEnabled ) 
            {
                TraceMarkup.Trace( TraceEventType.Start, TraceMarkup.Load ); 
            } 

            try 
            {
                if (null == stream)
                {
                    throw new ArgumentNullException("stream"); 
                }
 
                if (null == parserContext) 
                {
                    throw new ArgumentNullException("parserContext"); 
                }

                // Is this really the right thing to do? Can this XamlTypeMapper be reused?
                if (null == parserContext.XamlTypeMapper) 
                {
                    parserContext.XamlTypeMapper = XmlParserDefaults.DefaultMapper; 
                } 

                root = XmlTreeBuildAssembly(parserContext, stream, hooks, etwTracingEnabled); 
            }

            finally
            { 
                if( TraceMarkup.IsEnabled )
                { 
                    TraceMarkup.Trace( TraceEventType.Stop, TraceMarkup.Load, root ); 
                }
 
                if (etwTracingEnabled)
                {
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLGUID), MS.Utility.EventType.EndEvent);
                } 

#if DEBUG_CLR_MEM 
                if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) 
                {
                    CLRProfilerControl.CLRLogWriteLine("End_XamlParse_{0}", pass); 
                }
#endif // DEBUG_CLR_MEM
            }
 
            return (root);
        } 
 
        /// 
        /// Loads the given baml stream 
        /// 
        /// input as stream
        /// parent owner element of baml tree
        /// parser context 
        /// True if stream should be closed by the
        ///    parser after parsing is complete.  False if the stream should be left open 
        /// object root generated after baml parsed 
        /// 
        ///     Critical - because it sets _streamCreatedAssembly on the ParserContext, and that is 
        ///                SecurityCritical Data as this field is used by the BamlRecordReader to
        ///                allow legitimate internal types in Partial Trust.
        ///     Safe - because it gets this value from the stream if it implements an internal IStreamInfo
        ///            interface and IStreamInfo.Assembly is set by the ResourceContainer code that is 
        ///            SecurityCritical, but treated as safe.
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647
        internal static object LoadBaml( 
            Stream stream,
            ParserContext parserContext,
            object parent,
            bool closeStream) 
        {
            Debug.Assert(stream != null && parserContext != null); 
 
            bool etwTracingEnabled = false;
            object root = null; 

#if DEBUG_CLR_MEM
            bool clrTracingEnabled = false;
            // Use local pass variable to correctly log nested parses. 
            int pass = 0;
 
            if (CLRProfilerControl.ProcessIsUnderCLRProfiler && 
               (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance))
            { 
                clrTracingEnabled = true;
                pass = ++_CLRBamlPass;
                CLRProfilerControl.CLRLogWriteLine("Begin_BamlParse_{0}", pass);
            } 
#endif // DEBUG_CLR_MEM
 
            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal)) 
            {
                etwTracingEnabled = true; 
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEBAMLGUID), MS.Utility.EventType.StartEvent);
            }

            if( TraceMarkup.IsEnabled ) 
            {
                TraceMarkup.Trace( TraceEventType.Start, TraceMarkup.Load ); 
            } 

            try 
            {
                if (null == parserContext.XamlTypeMapper)
                {
                    parserContext.XamlTypeMapper = XmlParserDefaults.DefaultMapper; 
                }
 
                // 
                // If the stream contains info about the Assembly that created it,
                // set StreamCreatedAssembly from the stream instance. 
                //
                IStreamInfo streamInfo = stream as IStreamInfo;
                if (streamInfo != null)
                { 
                    parserContext.StreamCreatedAssembly = streamInfo.Assembly;
                } 
 
                TreeBuilderBamlTranslator treeBuilder = new TreeBuilderBamlTranslator(stream, parserContext, parent, closeStream);
 
                root = treeBuilder.Parse();

                Debug.Assert(parent == null || root == parent);
            } 

            finally 
            { 
                if( TraceMarkup.IsEnabled )
                { 
                    TraceMarkup.Trace( TraceEventType.Stop, TraceMarkup.Load, root );
                }

                if (etwTracingEnabled) 
                {
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEBAMLGUID), MS.Utility.EventType.EndEvent); 
                } 

#if DEBUG_CLR_MEM 
                if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance))
                {
                    CLRProfilerControl.CLRLogWriteLine("End_BamlParse_{0}", pass);
                } 
#endif // DEBUG_CLR_MEM
            } 
 
            return (root);
        } 

#endregion Internal Methods

#region Private Methods 
        /// 
        /// Reads XAML from the passed stream, building an object tree and returning the 
        /// root of that tree.  This override is used to pass settings used for validation. 
        /// 
        /// ParserContext 
        /// XmlReader
        /// Should wrap 'reader' with an XML Compatibility Reader
        /// Sets synchronous or asynchronous parsing
        /// input as bool 
        /// object root generated after xml parsed
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 
        private static object XmlTreeBuildDefault( 
            ParserContext pc,
            XmlReader     reader, 
            bool          wrapWithMarkupCompatReader,
            XamlParseMode parseMode,
            bool          etwTracingEnabled)
        { 
            XamlTreeBuilder treeBuilder = new XamlTreeBuilder(pc, reader, wrapWithMarkupCompatReader, parseMode);
 
            if (etwTracingEnabled) 
            {
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLINITIALIZEDGUID), MS.Utility.EventType.Info); 
            }

            object root = treeBuilder.Parse();
 
            return root;
        } 
 
        /// 
        /// Reads XAML from the passed stream, building an object tree and returning the 
        /// root of that tree.
        /// 
        /// ParserContext
        /// input as stream 
        /// Sets synchronous or asynchronous parsing
        /// input as bool 
        /// object root generated after xml parsed 
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647
        private static object XmlTreeBuildDefault( 
            ParserContext pc,
            Stream        stream,
            XamlParseMode parseMode,
            bool          etwTracingEnabled) 
        {
            XamlTreeBuilder treeBuilder = new XamlTreeBuilder(pc, stream, parseMode); 
 
            if (etwTracingEnabled)
            { 
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLINITIALIZEDGUID), MS.Utility.EventType.Info);
            }

            object root = treeBuilder.Parse(); 

            return root; 
        } 

        ///  
        /// Reads XAML from the passed stream, building an object tree and returning the
        /// root of that tree.
        /// 
        /// ParserContext 
        /// input as Stream
        /// hooks to callback during load 
        /// input as bool 
        /// object root generated after xml parsed
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 
        private static object XmlTreeBuildAssembly(
            ParserContext pc,
            Stream        stream,
            ParserHooks   hooks, 
            bool          etwTracingEnabled)
        { 
            // When we have ParserHooks we need to load synchronously 
            XamlTreeBuilder treeBuilder = new XamlTreeBuilder(pc, stream, XamlParseMode.Synchronous);
 
            treeBuilder.ParserHooks = hooks;

            if (etwTracingEnabled)
            { 
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.PARSEXMLINITIALIZEDGUID), MS.Utility.EventType.Info);
            } 
 
            object root = treeBuilder.Parse();
 
            return root;
        }
#endregion PrivateMethods
 
#region Data
 
        private XamlTreeBuilder _treeBuilder; 

#if DEBUG_CLR_MEM 
        private static int _CLRBamlPass = 0;
        private static int _CLRXamlPass = 0;
#endif
 
#endregion Data
    } 
} 

 

// 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