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
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- CriticalExceptions.cs
- ToolboxBitmapAttribute.cs
- UpdateRecord.cs
- GridViewPageEventArgs.cs
- HtmlObjectListAdapter.cs
- ConfigurationSection.cs
- ConcurrentDictionary.cs
- DoubleUtil.cs
- DirectionalLight.cs
- PointAnimationClockResource.cs
- Button.cs
- MbpInfo.cs
- SolidColorBrush.cs
- URIFormatException.cs
- RelatedView.cs
- CheckBoxStandardAdapter.cs
- Util.cs
- sapiproxy.cs
- InstanceHandleConflictException.cs
- BitmapMetadataEnumerator.cs
- SoapTypeAttribute.cs
- IndentedWriter.cs
- FormClosedEvent.cs
- GenericIdentity.cs
- QueueProcessor.cs
- DataGridViewRowHeaderCell.cs
- SqlServer2KCompatibilityCheck.cs
- InputLanguage.cs
- NativeMethods.cs
- RuntimeIdentifierPropertyAttribute.cs
- Selection.cs
- DBBindings.cs
- WindowsPrincipal.cs
- UrlPath.cs
- AuthorizationRule.cs
- XmlSchemaAttributeGroup.cs
- BaseCollection.cs
- TypeConverterValueSerializer.cs
- XmlRawWriterWrapper.cs
- XmlSchemaObject.cs
- JoinElimination.cs
- XmlSchemaImport.cs
- XDRSchema.cs
- Vector3DCollection.cs
- XmlNodeChangedEventArgs.cs
- SqlDataSourceView.cs
- streamingZipPartStream.cs
- ToolStripItemDesigner.cs
- OleDbInfoMessageEvent.cs
- EmptyQuery.cs
- ArrangedElementCollection.cs
- Soap.cs
- LineInfo.cs
- ByteStorage.cs
- HttpHostedTransportConfiguration.cs
- RadioButtonDesigner.cs
- MergePropertyDescriptor.cs
- FigureParaClient.cs
- BaseParagraph.cs
- WindowsUpDown.cs
- PropertyEntry.cs
- TextControl.cs
- SetIterators.cs
- ReplyChannel.cs
- StringBuilder.cs
- PropertyPath.cs
- ColumnResizeUndoUnit.cs
- SmiEventSink_Default.cs
- Function.cs
- XmlSerializationWriter.cs
- Transactions.cs
- UpdateException.cs
- DnsElement.cs
- StickyNote.cs
- LambdaCompiler.Generated.cs
- InkCanvasInnerCanvas.cs
- MetadataSource.cs
- DiscoveryClientProtocol.cs
- XmlReaderSettings.cs
- ColumnPropertiesGroup.cs
- SR.cs
- CacheRequest.cs
- DataBoundControlDesigner.cs
- QilInvokeLateBound.cs
- newitemfactory.cs
- ObjectDisposedException.cs
- DataGridViewCheckBoxCell.cs
- _OSSOCK.cs
- TiffBitmapEncoder.cs
- CodeTypeMember.cs
- RenderDataDrawingContext.cs
- TreeViewHitTestInfo.cs
- QueryOptionExpression.cs
- StylusTouchDevice.cs
- SwitchElementsCollection.cs
- Mouse.cs
- SessionStateContainer.cs
- InvalidEnumArgumentException.cs
- IndexedGlyphRun.cs
- TypedServiceOperationListItem.cs