Code:
/ 4.0 / 4.0 / 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.
//----------------------------------------------------------------------------
//
// 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
- DurationConverter.cs
- CancellationHandlerDesigner.cs
- HitTestFilterBehavior.cs
- IisNotInstalledException.cs
- EncodingTable.cs
- CryptoApi.cs
- ProfilePropertySettings.cs
- DetailsViewPagerRow.cs
- BitmapImage.cs
- ResolveCriteriaCD1.cs
- WpfWebRequestHelper.cs
- SqlDataSourceStatusEventArgs.cs
- RelationshipEndMember.cs
- panel.cs
- TypeConverter.cs
- ResourcePermissionBase.cs
- StoreItemCollection.cs
- SQLCharsStorage.cs
- Int32.cs
- Button.cs
- AssociationTypeEmitter.cs
- CursorConverter.cs
- KnownTypesProvider.cs
- SectionVisual.cs
- ImageCodecInfoPrivate.cs
- NameTable.cs
- EventSinkHelperWriter.cs
- TargetException.cs
- TextTreeRootTextBlock.cs
- PlaceHolder.cs
- AppSettingsExpressionBuilder.cs
- CTreeGenerator.cs
- handlecollector.cs
- SystemTcpConnection.cs
- EpmSyndicationContentDeSerializer.cs
- TrackingStringDictionary.cs
- SafeFileMapViewHandle.cs
- SID.cs
- CompiledIdentityConstraint.cs
- XmlEncoding.cs
- ThreadStaticAttribute.cs
- ObjectTag.cs
- RequestCachingSection.cs
- PatternMatchRules.cs
- ExpandCollapsePattern.cs
- ServiceHttpModule.cs
- KeyConverter.cs
- JsonWriter.cs
- FtpWebResponse.cs
- QueryExpr.cs
- ErrorProvider.cs
- RepeaterCommandEventArgs.cs
- ConnectionAcceptor.cs
- ModelItemExtensions.cs
- CapabilitiesSection.cs
- SessionState.cs
- XPathBinder.cs
- SymbolDocumentInfo.cs
- RowType.cs
- ConfigurationManager.cs
- StylusButtonCollection.cs
- XmlNavigatorStack.cs
- SoapObjectReader.cs
- TemplateBindingExpressionConverter.cs
- NestedContainer.cs
- SqlCommand.cs
- TextBlock.cs
- XmlUnspecifiedAttribute.cs
- OperationValidationEventArgs.cs
- RotateTransform3D.cs
- DynamicResourceExtensionConverter.cs
- ElapsedEventArgs.cs
- CheckBoxStandardAdapter.cs
- TypeLoadException.cs
- AccessorTable.cs
- CodeCommentStatementCollection.cs
- diagnosticsswitches.cs
- ToolStripDesignerAvailabilityAttribute.cs
- HealthMonitoringSection.cs
- KeyValuePairs.cs
- HMACSHA512.cs
- Base64Decoder.cs
- XmlProcessingInstruction.cs
- SplitterDesigner.cs
- XmlDownloadManager.cs
- DataListItemEventArgs.cs
- PlaceHolder.cs
- QueryResult.cs
- EntityDataSourceSelectedEventArgs.cs
- DataBoundControlAdapter.cs
- GenericsNotImplementedException.cs
- ClientRoleProvider.cs
- ManagementOptions.cs
- AnnotationHighlightLayer.cs
- SymbolTable.cs
- PasswordRecovery.cs
- DrawListViewSubItemEventArgs.cs
- DebugTracing.cs
- XmlILModule.cs
- Int32Rect.cs