XamlReader.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 / wpf / src / Framework / System / Windows / Markup / XamlReader.cs / 1599979 / 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; 
using System.Windows.Baml2006;
using System.Threading;
using System.Windows.Threading;
using System.Xaml; 
using System.Xaml.Permissions;
using System.Windows.Navigation; 
using MS.Internal.Xaml.Context; 

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) 
        { 
            if (stream == null)
            { 
                throw new ArgumentNullException("stream");
            }

            return Load(stream, null); 
        }
 
        ///  
        /// 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)
        { 
            if (reader == null) 
            {
                throw new ArgumentNullException("reader"); 
            }

            return Load(reader, null, XamlParseMode.Synchronous);
        } 

        ///  
        /// 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)
        { 
            if (stream == null) 
            {
                throw new ArgumentNullException("stream"); 
            }
            if (parserContext == null)
            {
                parserContext = new ParserContext(); 
            }
 
            XmlReader reader = XmlReader.Create(stream, null, parserContext); 
            object tree = Load(reader, parserContext, XamlParseMode.Synchronous);
            stream.Close(); 
            return tree;
        }

        ///  
        /// 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"); 
            }
            _stream = stream;

            if (_objectWriter != null) 
            {
                // A XamlReader instance cannot be shared across two load operations 
                throw new InvalidOperationException(SR.Get(SRID.ParserCannotReuseXamlReader)); 
            }
 
            return LoadAsync(stream, null);
        }

        ///  
        /// 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"); 
            }

            return LoadAsync(reader, null);
        } 

        ///  
        /// 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");
            } 
            _stream = stream;
 
            if (_objectWriter != null) 
            {
                // A XamlReader instance cannot be shared across two load operations 
                throw new InvalidOperationException(SR.Get(SRID.ParserCannotReuseXamlReader));
            }

            if (parserContext == null) 
            {
                parserContext = new ParserContext(); 
            } 

            XmlTextReader reader = new XmlTextReader(stream, XmlNodeType.Document, parserContext); 
            reader.DtdProcessing = DtdProcessing.Prohibit;
            return LoadAsync(reader, parserContext);
        }
 
        internal static bool ShouldReWrapException(Exception e, Uri baseUri)
        { 
            XamlParseException xpe = e as XamlParseException; 
            if (xpe != null)
            { 
                // If we can set, the BaseUri, rewrap; otherwise we don't need to
                return (xpe.BaseUri == null && baseUri != null);
            }
            // Not an XPE, so we need to wrap it 
            return true;
        } 
 
        private object LoadAsync(XmlReader reader, ParserContext parserContext)
        { 
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            } 

            if (parserContext == null) 
            { 
                parserContext = new ParserContext();
            } 

            _xmlReader = reader;
            object rootObject = null;
            if (parserContext.BaseUri == null || 
                 String.IsNullOrEmpty(parserContext.BaseUri.ToString()))
            { 
                if (reader.BaseURI == null || 
                    String.IsNullOrEmpty(reader.BaseURI.ToString()))
                { 
                    parserContext.BaseUri = BaseUriHelper.PackAppBaseUri;
                }
                else
                { 
                    parserContext.BaseUri = new Uri(reader.BaseURI);
                } 
            } 

            _baseUri = parserContext.BaseUri; 
            System.Xaml.XamlXmlReaderSettings settings = new System.Xaml.XamlXmlReaderSettings();
            settings.IgnoreUidsOnPropertyElements = true;
            settings.BaseUri = parserContext.BaseUri;
            settings.ProvideLineInfo = true; 
            XamlSchemaContext schemaContext = parserContext.XamlTypeMapper != null ?
                parserContext.XamlTypeMapper.SchemaContext : GetWpfSchemaContext(); 
 
            try
            { 
                _textReader = new System.Xaml.XamlXmlReader(reader, schemaContext, settings);

                _stack = new XamlContextStack(() => new WpfXamlFrame());
 
                System.Xaml.XamlObjectWriterSettings objectSettings = XamlReader.CreateObjectWriterSettings();
                objectSettings.AfterBeginInitHandler = delegate(object sender, System.Xaml.XamlObjectEventArgs args) 
                    { 
                        if (rootObject == null)
                        { 
                            rootObject = args.Instance;
                            _styleConnector = rootObject as IStyleConnector;
                        }
 
                        UIElement uiElement = args.Instance as UIElement;
                        if (uiElement != null) 
                        { 
                            uiElement.SetPersistId(_persistId++);
                        } 

                        DependencyObject dObject = args.Instance as DependencyObject;
                        if (dObject != null && _stack.CurrentFrame.XmlnsDictionary != null)
                        { 
                            XmlnsDictionary dictionary = _stack.CurrentFrame.XmlnsDictionary;
                            dictionary.Seal(); 
 
                            XmlAttributeProperties.SetXmlnsDictionary(dObject, dictionary);
                        } 
                    };

                _objectWriter = new System.Xaml.XamlObjectWriter(_textReader.SchemaContext, objectSettings);
                _parseCancelled = false; 
                _skipJournaledProperties = parserContext.SkipJournaledProperties;
 
                XamlMember synchronousModeProperty = _textReader.SchemaContext.GetXamlDirective("http://schemas.microsoft.com/winfx/2006/xaml", "SynchronousMode"); 
                XamlMember synchronousRecordProperty = _textReader.SchemaContext.GetXamlDirective("http://schemas.microsoft.com/winfx/2006/xaml", "AsyncRecords");
 
                System.Xaml.XamlReader xamlReader = _textReader;

                IXamlLineInfo xamlLineInfo = xamlReader as IXamlLineInfo;
                IXamlLineInfoConsumer xamlLineInfoConsumer = _objectWriter as IXamlLineInfoConsumer; 
                bool shouldPassLineNumberInfo = false;
                if ((xamlLineInfo != null && xamlLineInfo.HasLineInfo) 
                    && (xamlLineInfoConsumer != null && xamlLineInfoConsumer.ShouldProvideLineInfo)) 
                {
                    shouldPassLineNumberInfo = true; 
                }

                bool async = false;
                bool lastPropWasSyncMode = false; 
                bool lastPropWasSyncRecords = false;
 
                while (!_textReader.IsEof) 
                {
                    WpfXamlLoader.TransformNodes(xamlReader, _objectWriter, true /*onlyLoadOneNode*/, _skipJournaledProperties, shouldPassLineNumberInfo, xamlLineInfo, xamlLineInfoConsumer, _stack, _styleConnector); 

                    if (xamlReader.NodeType == System.Xaml.XamlNodeType.StartMember)
                    {
                        if (xamlReader.Member == synchronousModeProperty) 
                        {
                            lastPropWasSyncMode = true; 
                        } 
                        else if (xamlReader.Member == synchronousRecordProperty)
                        { 
                            lastPropWasSyncRecords = true;
                        }
                    }
                    else if (xamlReader.NodeType == System.Xaml.XamlNodeType.Value) 
                    {
                        if (lastPropWasSyncMode == true) 
                        { 
                            if (xamlReader.Value as String == "Async")
                            { 
                                async = true;
                            }
                        }
                        else if (lastPropWasSyncRecords == true) 
                        {
                            if (xamlReader.Value is int) 
                            { 
                                _maxAsynxRecords = (int)xamlReader.Value;
                            } 
                            else if (xamlReader.Value is String)
                            {
                                _maxAsynxRecords = Int32.Parse(xamlReader.Value as String, TypeConverterHelper.InvariantEnglishUS);
                            } 
                        }
                    } 
                    else if (xamlReader.NodeType == System.Xaml.XamlNodeType.EndMember) 
                    {
                        lastPropWasSyncMode = false; 
                        lastPropWasSyncRecords = false;
                    }

                    if (async && rootObject != null) 
                        break;
                } 
            } 
            catch (Exception e)
            { 
                // Don't wrap critical exceptions or already-wrapped exceptions.
                if (MS.Internal.CriticalExceptions.IsCriticalException(e) || !ShouldReWrapException(e, parserContext.BaseUri))
                {
                    throw; 
                }
                RewrapException(e, parserContext.BaseUri); 
            } 

            if (!_textReader.IsEof) 
            {
                Post();
                //ThreadStart threadStart = new ThreadStart(ReadXamlAsync);
                //Thread thread = new Thread(threadStart); 
                //thread.Start();
            } 
            else 
            {
                TreeBuildComplete(); 
            }

            if (rootObject is DependencyObject)
            { 
                if (parserContext.BaseUri != null && !String.IsNullOrEmpty(parserContext.BaseUri.ToString()))
                    (rootObject as DependencyObject).SetValue(BaseUriHelper.BaseUriProperty, parserContext.BaseUri); 
                //else 
                //    (rootObject as DependencyObject).SetValue(BaseUriHelper.BaseUriProperty, BaseUriHelper.PackAppBaseUri);
                WpfXamlLoader.EnsureXmlNamespaceMaps(rootObject, schemaContext); 
            }

            Application app = rootObject as Application;
            if (app != null) 
            {
                app.ApplicationMarkupBaseUri = GetBaseUri(settings.BaseUri); 
            } 

            return rootObject; 
        }

        // We need to rewrap exceptions to get them into standard form of XPE -> base exception
        internal static void RewrapException(Exception e, Uri baseUri) 
        {
            RewrapException(e, null, baseUri); 
        } 

        internal static void RewrapException(Exception e, IXamlLineInfo lineInfo, Uri baseUri) 
        {
            throw WrapException(e, lineInfo, baseUri);
        }
 
        internal static XamlParseException WrapException(Exception e, IXamlLineInfo lineInfo, Uri baseUri)
        { 
            Exception baseException = (e.InnerException == null) ? e : e.InnerException; 
            if (baseException is System.Windows.Markup.XamlParseException)
            { 
                var xe = ((System.Windows.Markup.XamlParseException)baseException);
                xe.BaseUri = xe.BaseUri ?? baseUri;
                if (lineInfo != null && xe.LinePosition == 0 && xe.LineNumber == 0)
                { 
                    xe.LinePosition = lineInfo.LinePosition;
                    xe.LineNumber = lineInfo.LineNumber; 
                } 
                return xe;
            } 
            if (e is System.Xaml.XamlException)
            {
                System.Xaml.XamlException xe = (System.Xaml.XamlException)e;
                return new XamlParseException(xe.Message, xe.LineNumber, xe.LinePosition, baseUri, baseException); 
            }
            else if (e is XmlException) 
            { 
                XmlException xe = (XmlException)e;
                return new XamlParseException(xe.Message, xe.LineNumber, xe.LinePosition, baseUri, baseException); 
            }
            else
            {
                if (lineInfo != null) 
                {
                    return new XamlParseException(e.Message, lineInfo.LineNumber, lineInfo.LinePosition, baseUri, baseException); 
                } 
                else
                { 
                    return new XamlParseException(e.Message, baseException);
                }
            }
        } 

 
        ///  
        ///  Post a queue item at default priority
        ///  
        internal void Post()
        {
            Post(DispatcherPriority.Background);
        } 

        ///  
        ///  Post a queue item at the specified priority 
        /// 
        internal void Post(DispatcherPriority priority) 
        {
            DispatcherOperationCallback callback = new DispatcherOperationCallback(Dispatch);
            Dispatcher.CurrentDispatcher.BeginInvoke(priority, callback, this);
        } 

        ///  
        ///  Dispatch delegate 
        /// 
        private object Dispatch(object o) 
        {
            DispatchParserQueueEvent((XamlReader)o);
            return null;
        } 

        private void DispatchParserQueueEvent(XamlReader xamlReader) 
        { 
            xamlReader.HandleAsyncQueueItem();
        } 

        const int AsyncLoopTimeout = (int)200;

        ///  
        /// called when in async mode when get a time slice to read and load the Tree
        ///  
        internal virtual void HandleAsyncQueueItem() 
        {
            try 
            {
                int startTickCount = MS.Win32.SafeNativeMethods.GetTickCount();
                //bool moreData = true;
 
                // for debugging, can set the Maximum Async records to
                // read via markup 
                // x:AsyncRecords="3" would loop three times 
                // Todo: This should either be removed at some point
                int maxRecords = _maxAsynxRecords; 

                System.Xaml.XamlReader xamlReader = _textReader;

                IXamlLineInfo xamlLineInfo = xamlReader as IXamlLineInfo; 
                IXamlLineInfoConsumer xamlLineInfoConsumer = _objectWriter as IXamlLineInfoConsumer;
                bool shouldPassLineNumberInfo = false; 
                if ((xamlLineInfo != null && xamlLineInfo.HasLineInfo) 
                    && (xamlLineInfoConsumer != null && xamlLineInfoConsumer.ShouldProvideLineInfo))
                { 
                    shouldPassLineNumberInfo = true;
                }

                XamlMember synchronousRecordProperty = _textReader.SchemaContext.GetXamlDirective(XamlLanguage.Xaml2006Namespace, "AsyncRecords"); 

                while (!xamlReader.IsEof && !_parseCancelled) 
                { 
                    WpfXamlLoader.TransformNodes(xamlReader, _objectWriter, true /*onlyLoadOneNode*/, _skipJournaledProperties, shouldPassLineNumberInfo, xamlLineInfo, xamlLineInfoConsumer, _stack, _styleConnector);
 
                    if (xamlReader.NodeType == System.Xaml.XamlNodeType.Value && _stack.CurrentFrame.Property == synchronousRecordProperty)
                    {
                        if (xamlReader.Value is int)
                        { 
                            _maxAsynxRecords = (int)xamlReader.Value;
                        } 
                        else if (xamlReader.Value is String) 
                        {
                            _maxAsynxRecords = Int32.Parse(xamlReader.Value as String, TypeConverterHelper.InvariantEnglishUS); 
                        }
                        maxRecords = _maxAsynxRecords;
                    }
 
                    //Debug.Assert (1 >= RootList.Count, "Multiple roots not supported in async mode");
 
                    // check the timeout 
                    int elapsed = MS.Win32.SafeNativeMethods.GetTickCount() - startTickCount;
 
                    // check for rollover
                    if (elapsed < 0)
                    {
                        startTickCount = 0; // reset to 0, 
                    }
                    else if (elapsed > AsyncLoopTimeout) 
                    { 
                        break;
                    } 

                    // decrement and compare with zero so the unitialized -1  and zero case
                    // doesn't break the loop.
                    if (--maxRecords == 0) 
                    {
                        break; 
                    } 
                }
            } 
            catch (XamlParseException e)
            {
                _parseException = e;
            } 
            catch (Exception e)
            { 
                if (CriticalExceptions.IsCriticalException(e) || !XamlReader.ShouldReWrapException(e, _baseUri)) 
                {
                    _parseException = e; 
                }
                else
                {
                    _parseException = XamlReader.WrapException(e, null, _baseUri); 
                }
            } 
            finally 
            {
                if (_parseException != null || _parseCancelled) 
                {
                    TreeBuildComplete();
                }
                else 
                {
                    // if not at the EndOfDocument then post another work item 
                    if (false == _textReader.IsEof) 
                    {
                        Post(); 
                    }
                    else
                    {
                        // Building of the Tree is complete. 
                        TreeBuildComplete();
                    } 
                } 
            }
        } 

        internal void TreeBuildComplete()
        {
            //if (ParseCompleted != null) 
            //{
            if (LoadCompleted != null) 
            { 
                // Fire the ParseCompleted event asynchronously
                Dispatcher.CurrentDispatcher.BeginInvoke( 
                    DispatcherPriority.Normal,
                    (DispatcherOperationCallback)delegate(object obj)
                    {
                        LoadCompleted(this, new AsyncCompletedEventArgs(_parseException, _parseCancelled, null)); 
                        return null;
                    }, 
                    null); 
            }
            //} 
            _xmlReader.Close();
            _objectWriter = null;
            _stream = null;
            _textReader = null; 
            _stack = null;
        } 
 

        ///  
        /// 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()
        { 
            _parseCancelled = true;
        }

        ///  
        /// 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
        internal static XamlObjectWriterSettings CreateObjectWriterSettings() 
        {
            XamlObjectWriterSettings owSettings = new XamlObjectWriterSettings(); 
            owSettings.IgnoreCanConvert = true; 
            owSettings.PreferUnconvertedDictionaryKeys = true;
            return owSettings; 
        }

        internal static XamlObjectWriterSettings CreateObjectWriterSettings(XamlObjectWriterSettings parentSettings)
        { 
            XamlObjectWriterSettings owSettings = CreateObjectWriterSettings();
            if (parentSettings != null) 
            { 
                owSettings.SkipDuplicatePropertyCheck = parentSettings.SkipDuplicatePropertyCheck;
                owSettings.AccessLevel = parentSettings.AccessLevel; 
                owSettings.SkipProvideValueOnRoot = parentSettings.SkipProvideValueOnRoot;
            }
            return owSettings;
        } 

        internal static XamlObjectWriterSettings CreateObjectWriterSettingsForBaml() 
        { 
            XamlObjectWriterSettings owSettings = CreateObjectWriterSettings();
            owSettings.SkipDuplicatePropertyCheck = true; 
            return owSettings;
        }

        internal static Baml2006ReaderSettings CreateBamlReaderSettings() 
        {
            Baml2006ReaderSettings brSettings = new Baml2006ReaderSettings(); 
            brSettings.IgnoreUidsOnPropertyElements = true; 
            return brSettings;
        } 

        internal static XamlSchemaContextSettings CreateSchemaContextSettings()
        {
            XamlSchemaContextSettings xscSettings = new XamlSchemaContextSettings(); 
            xscSettings.SupportMarkupExtensionsWithDuplicateArity = true;
            return xscSettings; 
        } 

        internal static WpfSharedBamlSchemaContext BamlSharedSchemaContext { get { return _bamlSharedContext.Value; } } 
        internal static WpfSharedBamlSchemaContext XamlV3SharedSchemaContext { get { return _xamlV3SharedContext.Value; } }
        public static XamlSchemaContext GetWpfSchemaContext()
        {
            return _xamlSharedContext.Value; 
        }
 
        ///  
        /// 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 parserContext,
            XamlParseMode parseMode) 
        {
            if (parseMode == XamlParseMode.Uninitialized || 
                parseMode == XamlParseMode.Asynchronous) 
            {
                XamlReader xamlReader = new XamlReader(); 
                return xamlReader.LoadAsync(reader, parserContext);
            }

            if (parserContext == null) 
            {
                parserContext = new ParserContext(); 
            } 

#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
 
            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml, EventTrace.Event.WClientParseXmlBegin, parserContext.BaseUri);
 
            if (TraceMarkup.IsEnabled) 
            {
                TraceMarkup.Trace(TraceEventType.Start, TraceMarkup.Load); 
            }
            object root = null;
            try
            { 

                if (parserContext.BaseUri == null || 
                    String.IsNullOrEmpty(parserContext.BaseUri.ToString())) 
                {
                    if (reader.BaseURI == null || 
                        String.IsNullOrEmpty(reader.BaseURI.ToString()))
                    {
                        parserContext.BaseUri = BaseUriHelper.PackAppBaseUri;
                    } 
                    else
                    { 
                        parserContext.BaseUri = new Uri(reader.BaseURI); 
                    }
                } 

                System.Xaml.XamlXmlReaderSettings settings = new System.Xaml.XamlXmlReaderSettings();
                settings.IgnoreUidsOnPropertyElements = true;
                settings.BaseUri = parserContext.BaseUri; 
                settings.ProvideLineInfo = true;
 
                XamlSchemaContext schemaContext = parserContext.XamlTypeMapper != null ? 
                    parserContext.XamlTypeMapper.SchemaContext : GetWpfSchemaContext();
                System.Xaml.XamlXmlReader xamlXmlReader = new System.Xaml.XamlXmlReader(reader, schemaContext, settings); 
                root = Load(xamlXmlReader, parserContext);
                reader.Close();
            }
            catch (Exception e) 
            {
                // Don't wrap critical exceptions or already-wrapped exceptions. 
                if(MS.Internal.CriticalExceptions.IsCriticalException(e) || !ShouldReWrapException(e, parserContext.BaseUri)) 
                {
                    throw; 
                }
                RewrapException(e, parserContext.BaseUri);
            }
            finally 
            {
                if (TraceMarkup.IsEnabled) 
                { 
                    TraceMarkup.Trace(TraceEventType.Stop, TraceMarkup.Load, root);
                } 

                EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml, EventTrace.Event.WClientParseXmlEnd, parserContext.BaseUri);

#if DEBUG_CLR_MEM 
                if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance))
                { 
                    CLRProfilerControl.CLRLogWriteLine("End_XamlParse_{0}", pass); 
                }
#endif // DEBUG_CLR_MEM 
            }
            return root;
        }
 
        internal static object Load(
            System.Xaml.XamlReader xamlReader, 
            ParserContext parserContext) 
        {
            if (parserContext == null) 
            {
                parserContext = new ParserContext();
            }
 
            // In some cases, the application constructor is not run prior to loading,
            // causing the loader not to recognize URIs beginning with "pack:" or "application:". 
            MS.Internal.WindowsBase.SecurityHelper.RunClassConstructor(typeof(System.Windows.Application)); 

            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml | EventTrace.Keyword.KeywordPerf, EventTrace.Event.WClientParseXamlBegin, parserContext.BaseUri); 

            object root = WpfXamlLoader.Load(xamlReader, parserContext.SkipJournaledProperties, parserContext.BaseUri);

            DependencyObject dObject = root as DependencyObject; 
            if (dObject != null)
            { 
                if (parserContext.BaseUri != null && !String.IsNullOrEmpty(parserContext.BaseUri.ToString())) 
                {
                    dObject.SetValue(BaseUriHelper.BaseUriProperty, parserContext.BaseUri); 
                }
            }

            Application app = root as Application; 
            if (app != null)
            { 
                app.ApplicationMarkupBaseUri = GetBaseUri(parserContext.BaseUri); 
            }
 
            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml | EventTrace.Keyword.KeywordPerf, EventTrace.Event.WClientParseXamlEnd, parserContext.BaseUri);

            return root;
        } 

        public static object Load(System.Xaml.XamlReader reader) 
        { 
            if (reader == null)
            { 
                throw new ArgumentNullException("reader");
            }
            object root = null;
            try 
            {
                root = Load(reader, null); 
            } 
            catch (Exception e)
            { 
                IUriContext uriContext = reader as IUriContext;
                Uri baseUri = (uriContext != null) ? uriContext.BaseUri : null;
                // Don't wrap critical exceptions or already-wrapped exceptions.
                if (MS.Internal.CriticalExceptions.IsCriticalException(e) || !ShouldReWrapException(e, baseUri)) 
                {
                    throw; 
                } 
                RewrapException(e, baseUri);
            } 
            finally
            {
                if (TraceMarkup.IsEnabled)
                { 
                    TraceMarkup.Trace(TraceEventType.Stop, TraceMarkup.Load, root);
                } 
 
                EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml, EventTrace.Event.WClientParseXmlEnd);
 
#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 asserts XamlLoadPermission, which is demanded by ObjectWriter 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) 
        { 
            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 

            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml | EventTrace.Keyword.KeywordPerf, EventTrace.Event.WClientParseBamlBegin, parserContext.BaseUri); 
 
            if (TraceMarkup.IsEnabled)
            { 
                TraceMarkup.Trace(TraceEventType.Start, TraceMarkup.Load);
            }

            try 
            {
                // 
                // 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; 
                }
 
                Baml2006ReaderSettings readerSettings = XamlReader.CreateBamlReaderSettings(); 
                readerSettings.BaseUri = parserContext.BaseUri;
                readerSettings.LocalAssembly = streamInfo.Assembly; 
 				// We do not set OwnsStream = true so the Baml2006Reader will not close the stream.
                // Calling code is responsible for disposing the stream
                if (readerSettings.BaseUri == null || String.IsNullOrEmpty(readerSettings.BaseUri.ToString()))
                { 
                    readerSettings.BaseUri = BaseUriHelper.PackAppBaseUri;
                } 
 
                var reader = new Baml2006Reader(stream, new Baml2006SchemaContext(readerSettings.LocalAssembly), readerSettings, parent);
 
                // We don't actually use the GeneratedInternalTypeHelper any more.
                // But for v3 compat, don't allow loading of internals in PT unless there is one.
                Type internalTypeHelper = null;
                if (streamInfo.Assembly != null) 
                {
                    try 
                    { 
                        internalTypeHelper = XamlTypeMapper.GetInternalTypeHelperTypeFromAssembly(parserContext);
                    } 
                    // This can perform attribute reflection which will fail if the assembly has unresolvable
                    // attributes. If that happens, just assume there is no helper.
                    catch (Exception e)
                    { 
                        if (MS.Internal.CriticalExceptions.IsCriticalException(e))
                        { 
                            throw; 
                        }
                    } 
                }

                if (internalTypeHelper != null)
                { 
                    XamlAccessLevel accessLevel = XamlAccessLevel.AssemblyAccessTo(streamInfo.Assembly);
                    XamlLoadPermission loadPermission = new XamlLoadPermission(accessLevel); 
                    loadPermission.Assert(); 
                    try
                    { 
                        root = WpfXamlLoader.LoadBaml(reader, parserContext.SkipJournaledProperties, parent, accessLevel, parserContext.BaseUri);
                    }
                    finally
                    { 
                        CodeAccessPermission.RevertAssert();
                    } 
                } 
                else
                { 
                    root = WpfXamlLoader.LoadBaml(reader, parserContext.SkipJournaledProperties, parent, null, parserContext.BaseUri);
                }

                DependencyObject dObject = root as DependencyObject; 
                if (dObject != null)
                { 
                    dObject.SetValue(BaseUriHelper.BaseUriProperty, readerSettings.BaseUri); 
                }
 
                Application app = root as Application;
                if (app != null)
                {
                    app.ApplicationMarkupBaseUri = GetBaseUri(readerSettings.BaseUri); 
                }
 
                Debug.Assert(parent == null || root == parent); 
            }
 
            finally
            {
                if (TraceMarkup.IsEnabled)
                { 
                    TraceMarkup.Trace(TraceEventType.Stop, TraceMarkup.Load, root);
                } 
 
                EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml | EventTrace.Keyword.KeywordPerf, EventTrace.Event.WClientParseBamlEnd, parserContext.BaseUri);
 
				if (closeStream && stream != null)
                {
                    stream.Close();
                } 

#if DEBUG_CLR_MEM 
                if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) 
                {
                    CLRProfilerControl.CLRLogWriteLine("End_BamlParse_{0}", pass); 
                }
#endif // DEBUG_CLR_MEM
            }
 
            return (root);
        } 
 
        static Uri GetBaseUri(Uri uri)
        { 
            if (uri == null)
            {
                return MS.Internal.Utility.BindUriHelper.BaseUri;
            } 
            else if (uri.IsAbsoluteUri == false)
            { 
                return new Uri(MS.Internal.Utility.BindUriHelper.BaseUri, uri); 
            }
 
            return uri;
        }

        private static WpfSharedBamlSchemaContext CreateBamlSchemaContext() 
        {
            XamlSchemaContextSettings settings = new XamlSchemaContextSettings(); 
            settings.SupportMarkupExtensionsWithDuplicateArity = true; 
            return new WpfSharedBamlSchemaContext(settings);
        } 

        private static WpfSharedXamlSchemaContext CreateXamlSchemaContext(bool useV3Rules)
        {
            XamlSchemaContextSettings settings = new XamlSchemaContextSettings(); 
            settings.SupportMarkupExtensionsWithDuplicateArity = true;
            return new WpfSharedXamlSchemaContext(settings, useV3Rules); 
        } 

        #endregion Internal Methods 

        #region Data

        private Uri _baseUri; 
        private System.Xaml.XamlReader _textReader;
        private XmlReader _xmlReader; 
        private System.Xaml.XamlObjectWriter _objectWriter; 
        private Stream _stream;
        private bool _parseCancelled; 
        private Exception _parseException;
        private int _persistId = 1;
        private bool _skipJournaledProperties;
        private XamlContextStack _stack; 
        private int _maxAsynxRecords = -1;
        private IStyleConnector _styleConnector; 
        private static readonly Lazy _bamlSharedContext = 
            new Lazy(() => CreateBamlSchemaContext());
        private static readonly Lazy _xamlSharedContext = 
            new Lazy(() => CreateXamlSchemaContext(false));
        private static readonly Lazy _xamlV3SharedContext =
            new Lazy(() => CreateXamlSchemaContext(true));
 
#if DEBUG_CLR_MEM
        private static int _CLRBamlPass = 0; 
        private static int _CLRXamlPass = 0; 
#endif
 
        #endregion Data
    }

    internal class WpfXamlFrame : XamlFrame 
    {
        public WpfXamlFrame() { } 
        public bool FreezeFreezable { get; set; } 
        public XamlMember Property { get; set; }
        public XamlType Type { get; set; } 
        public object Instance { get; set; }
        public XmlnsDictionary XmlnsDictionary { get; set; }
        public bool? XmlSpace { get; set; }
 
        public override void Reset()
        { 
            Type = null; 
            Property = null;
            Instance = null; 
            XmlnsDictionary = null;
            XmlSpace = null;
            if (FreezeFreezable)
            { 
                FreezeFreezable = false;
            } 
        } 
    }
} 

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