Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Markup / XamlParser.cs / 1305600 / XamlParser.cs
/****************************************************************************\ * * File: XamlParser.cs * * Purpose: Class for compiling Xaml. * * History: * 6/06/01: rogerg Created * 5/28/03: peterost Ported to wcp * 10/6/03: peterost Reorganized to remove DP - clr distinction * * Copyright (C) 2003 by Microsoft Corporation. All rights reserved. * \***************************************************************************/ using System; using System.Xml; using System.IO; using System.Text; using System.Collections; using System.ComponentModel; using System.Diagnostics; using System.Reflection; using System.Globalization; using System.Security.Permissions; using MS.Utility; using System.Runtime.InteropServices; using MS.Internal; // Disabling 1634 and 1691: // In order to avoid generating warnings about unknown message numbers and // unknown pragmas when compiling C# source code with the C# compiler, // you need to disable warnings 1634 and 1691. (Presharp Documentation) #pragma warning disable 1634, 1691 #if PBTCOMPILER namespace MS.Internal.Markup #else using System.Windows; namespace System.Windows.Markup #endif { #region enums ////// Parser modes. indicates if the Xaml should be parsed [....] or async. /// currently public so test can set these values. /// internal enum XamlParseMode { ////// Not initialized /// Uninitialized, ////// [....] /// Synchronous, ////// Async /// Asynchronous, } #endregion enums ////// XamlParser class. This class is used internally /// internal class XamlParser { #if PBTCOMPILER #region Constructors ////// Constructor that takes a stream and creates an XmlCompatibilityReader on it. /// public XamlParser( ParserContext parserContext, BamlRecordWriter bamlWriter, Stream xamlStream, bool multipleRoots) : this(parserContext, bamlWriter, new XmlTextReader(xamlStream, multipleRoots ? XmlNodeType.Element : XmlNodeType.Document, (XmlParserContext)parserContext) ) { } protected XamlParser( ParserContext parserContext, BamlRecordWriter bamlWriter, XmlTextReader textReader) : this(parserContext, bamlWriter) { // When the XML 1.0 specification was authored, security was not a top concern, and as a result DTDs have the // unfortunate capability of severe Denial of Service (DoS) attacks, typically through the use of an internal // entity expansion technique. In System.Xml V2.0, in order to provide protection against DTD DoS attacks there // is the capability of turning off DTD parsing through the use of the ProhibitDtd property. textReader.ProhibitDtd = true; XmlCompatibilityReader xcr = new XmlCompatibilityReader(textReader, new IsXmlNamespaceSupportedCallback(IsXmlNamespaceSupported), _predefinedNamespaces ); TokenReader = new XamlReaderHelper(this,parserContext,xcr); } protected XamlParser( ParserContext parserContext, BamlRecordWriter bamlWriter) { _parserContext = parserContext; _bamlWriter = bamlWriter; } // Default constructor to aid in subclassing protected XamlParser() { } #endregion Constructors #region PublicMethods ////// Main method to Parse the XAML. /// When in synchronous mode the entire file is parsed before /// this method returns. /// In asynchronous mode at least the root tag is parsed. This /// is necessary for the way binders currently work. /// public void Parse() { // if parseMode hasn't been set then set it now to synchronous. if (XamlParseMode == XamlParseMode.Uninitialized) { XamlParseMode = XamlParseMode.Synchronous; } _Parse(); } ////// Main function called by the XamlCompiler on a Compile. /// If singleRecordMode is true the Read returns after each item read. /// ///True if more nodes to read // !! Review - now that have separate out into XamlReaderHelper // review if still need all the virtuals or the caller of the TokenReader // can dispatch as they feel appropriate. public bool ReadXaml(bool singleRecordMode) { XamlNode xamlNode = null; bool cleanup = !singleRecordMode; bool done = false; try // What do we do with Exceptions we catch on this thread?. { while (TokenReader.Read(ref xamlNode)) { SetParserAction(xamlNode); if (ParserAction == ParserAction.Normal) { // If processing of the xaml node determines that we are done, // then stop now. This can happen if ProcessXamlNode is // overridden (such as when processing styles) and the parsed // block is finished, but the overall file is not. In that // case exit this parser, but leave everything intact. ProcessXamlNode(xamlNode, ref cleanup, ref done); if (done) { break; } // return here in single record mode since we don't want // to set the parser loop to Done. if (singleRecordMode) { return true; } } } } catch (Exception e) { if (CriticalExceptions.IsCriticalException(e)) { throw; } else { if (e is XamlParseException) { throw; } // If the exception was a XamlParse exception on the other // side of a Reflection Invoke, then just pull up the Parse exception. if (e is TargetInvocationException && e.InnerException is XamlParseException) { throw e.InnerException; } int lineNumber = 0; int linePosition = 0; string newMessage = null; if (e is XmlException) { XmlException xmlEx = (XmlException)e; lineNumber = xmlEx.LineNumber; linePosition = xmlEx.LinePosition; newMessage = xmlEx.Message; } else { // generic exception, If have a xamlNode then use the // nodes values for the line Numbers. if (null != xamlNode) { lineNumber = xamlNode.LineNumber; linePosition = xamlNode.LinePosition; } newMessage = e.Message + " " + SR.Get(SRID.ParserLineAndOffset, lineNumber.ToString(CultureInfo.CurrentCulture), linePosition.ToString(CultureInfo.CurrentCulture)); } XamlParseException parseException = new XamlParseException(newMessage, lineNumber, linePosition, e); ParseError(parseException); // Recurse on error cleanup = true; throw parseException; } } finally { // Perform cleanup only if we encountered a non-recoverable error, or // we're finished reading the stream (EndDocument reached in single // record mode, or end of stream reached in multi-record mode) if (cleanup) { // Close the reader, which will close the underlying stream. TokenReader.Close(); } } return false; } ////// Big switch to handle all the records. /// /// Node received from TokenReader to process /// True if end of stream reached and document is /// totally finished and should be closed /// True if done processing and want to exit. Doesn't /// necessarily mean document is finished (see cleanup) internal virtual void ProcessXamlNode( XamlNode xamlNode, ref bool cleanup, ref bool done) { switch(xamlNode.TokenType) { case XamlNodeType.DocumentStart: XamlDocumentStartNode xamlDocumentStartNode = (XamlDocumentStartNode) xamlNode; WriteDocumentStart(xamlDocumentStartNode); break; case XamlNodeType.DocumentEnd: XamlDocumentEndNode xamlEndDocumentNode = (XamlDocumentEndNode) xamlNode; cleanup = true; done = true; WriteDocumentEnd(xamlEndDocumentNode); break; case XamlNodeType.ElementStart: XamlElementStartNode xamlElementNode = (XamlElementStartNode) xamlNode; WriteElementStart(xamlElementNode); break; case XamlNodeType.ElementEnd: XamlElementEndNode xamlEndElementNode = (XamlElementEndNode) xamlNode; WriteElementEnd(xamlEndElementNode); break; case XamlNodeType.UnknownTagStart: XamlUnknownTagStartNode xamlUnknownTagStartNode = (XamlUnknownTagStartNode) xamlNode; WriteUnknownTagStart(xamlUnknownTagStartNode); break; case XamlNodeType.UnknownTagEnd: XamlUnknownTagEndNode xamlUnknownTagEndNode = (XamlUnknownTagEndNode) xamlNode; WriteUnknownTagEnd(xamlUnknownTagEndNode); break; case XamlNodeType.XmlnsProperty: XamlXmlnsPropertyNode xamlXmlnsPropertyNode = (XamlXmlnsPropertyNode) xamlNode; WriteNamespacePrefix(xamlXmlnsPropertyNode); break; case XamlNodeType.Property: XamlPropertyNode xamlPropertyNode = (XamlPropertyNode) xamlNode; if (xamlPropertyNode.AttributeUsage == BamlAttributeUsage.RuntimeName) { _parserContext.XamlTypeMapper.ValidateNames( xamlPropertyNode.Value, xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition); } WriteProperty(xamlPropertyNode); break; case XamlNodeType.PropertyWithExtension: XamlPropertyWithExtensionNode xamlPropertyWithExtensionNode = (XamlPropertyWithExtensionNode)xamlNode; WritePropertyWithExtension(xamlPropertyWithExtensionNode); break; case XamlNodeType.PropertyWithType: XamlPropertyWithTypeNode xamlPropertyWithTypeNode = (XamlPropertyWithTypeNode) xamlNode; WritePropertyWithType(xamlPropertyWithTypeNode); break; case XamlNodeType.UnknownAttribute: XamlUnknownAttributeNode xamlUnknownAttributeNode = (XamlUnknownAttributeNode) xamlNode; WriteUnknownAttribute(xamlUnknownAttributeNode); break; case XamlNodeType.PropertyComplexStart: XamlPropertyComplexStartNode xamlPropertyComplexStartNode = (XamlPropertyComplexStartNode) xamlNode; WritePropertyComplexStart(xamlPropertyComplexStartNode); break; case XamlNodeType.PropertyComplexEnd: XamlPropertyComplexEndNode xamlPropertyComplexEndNode = (XamlPropertyComplexEndNode) xamlNode; WritePropertyComplexEnd(xamlPropertyComplexEndNode); break; case XamlNodeType.LiteralContent: XamlLiteralContentNode xamlLiteralContentNode = (XamlLiteralContentNode) xamlNode; WriteLiteralContent(xamlLiteralContentNode); break; case XamlNodeType.Text: XamlTextNode xamlTextNode = (XamlTextNode) xamlNode; WriteText(xamlTextNode); break; case XamlNodeType.ClrEvent: XamlClrEventNode xamlClrEventNode = (XamlClrEventNode) xamlNode; WriteClrEvent(xamlClrEventNode); break; case XamlNodeType.PropertyArrayStart: XamlPropertyArrayStartNode xamlPropertyArrayStartNode = (XamlPropertyArrayStartNode) xamlNode; WritePropertyArrayStart(xamlPropertyArrayStartNode); break; case XamlNodeType.PropertyArrayEnd: XamlPropertyArrayEndNode xamlPropertyArrayEndNode = (XamlPropertyArrayEndNode) xamlNode; WritePropertyArrayEnd(xamlPropertyArrayEndNode); break; case XamlNodeType.PropertyIListStart: XamlPropertyIListStartNode xamlPropertyIListStartNode = (XamlPropertyIListStartNode) xamlNode; WritePropertyIListStart(xamlPropertyIListStartNode); break; case XamlNodeType.PropertyIListEnd: XamlPropertyIListEndNode xamlPropertyIListEndNode = (XamlPropertyIListEndNode) xamlNode; WritePropertyIListEnd(xamlPropertyIListEndNode); break; case XamlNodeType.PropertyIDictionaryStart: XamlPropertyIDictionaryStartNode xamlPropertyIDictionaryStartNode = (XamlPropertyIDictionaryStartNode) xamlNode; WritePropertyIDictionaryStart(xamlPropertyIDictionaryStartNode); break; case XamlNodeType.PropertyIDictionaryEnd: XamlPropertyIDictionaryEndNode xamlPropertyIDictionaryEndNode = (XamlPropertyIDictionaryEndNode) xamlNode; WritePropertyIDictionaryEnd(xamlPropertyIDictionaryEndNode); break; case XamlNodeType.DefTag: XamlDefTagNode xamlDefTagNode = (XamlDefTagNode) xamlNode; WriteDefTag(xamlDefTagNode); break; case XamlNodeType.DefKeyTypeAttribute: XamlDefAttributeKeyTypeNode xamlDefAttributeKeyTypeNode = (XamlDefAttributeKeyTypeNode) xamlNode; WriteDefAttributeKeyType(xamlDefAttributeKeyTypeNode); break; case XamlNodeType.DefAttribute: XamlDefAttributeNode xamlDefAttributeNode = (XamlDefAttributeNode) xamlNode; if (xamlDefAttributeNode.AttributeUsage == BamlAttributeUsage.RuntimeName) { _parserContext.XamlTypeMapper.ValidateNames( xamlDefAttributeNode.Value, xamlDefAttributeNode.LineNumber, xamlDefAttributeNode.LinePosition); } WriteDefAttributeCore(xamlDefAttributeNode); break; case XamlNodeType.PresentationOptionsAttribute: XamlPresentationOptionsAttributeNode xamlPresentationOptionsAttributeNode = (XamlPresentationOptionsAttributeNode) xamlNode; WritePresentationOptionsAttribute(xamlPresentationOptionsAttributeNode); break; case XamlNodeType.PIMapping: XamlPIMappingNode xamlPIMappingNode = (XamlPIMappingNode) xamlNode; WritePIMapping(xamlPIMappingNode); break; // The following tokens that are used primarily by the markup compiler case XamlNodeType.EndAttributes: XamlEndAttributesNode xamlEndAttributesNode = (XamlEndAttributesNode) xamlNode; // if first tag and haven't alredy set the ParseMode // set it to synchronous. if (0 == xamlEndAttributesNode.Depth) { if (XamlParseMode == XamlParseMode.Uninitialized) { XamlParseMode = XamlParseMode.Synchronous; } } WriteEndAttributes(xamlEndAttributesNode); break; case XamlNodeType.KeyElementStart: XamlKeyElementStartNode xamlKeyElementStartNode = (XamlKeyElementStartNode) xamlNode; WriteKeyElementStart(xamlKeyElementStartNode); break; case XamlNodeType.KeyElementEnd: XamlKeyElementEndNode xamlKeyElementEndNode = (XamlKeyElementEndNode) xamlNode; WriteKeyElementEnd(xamlKeyElementEndNode); break; case XamlNodeType.ConstructorParametersEnd: XamlConstructorParametersEndNode xamlConstructorParametersEndNode = (XamlConstructorParametersEndNode) xamlNode; WriteConstructorParametersEnd(xamlConstructorParametersEndNode); break; case XamlNodeType.ConstructorParametersStart: XamlConstructorParametersStartNode xamlConstructorParametersStartNode = (XamlConstructorParametersStartNode) xamlNode; WriteConstructorParametersStart(xamlConstructorParametersStartNode); break; case XamlNodeType.ContentProperty: XamlContentPropertyNode xamlContentPropertyNode = (XamlContentPropertyNode)xamlNode; WriteContentProperty(xamlContentPropertyNode); break; case XamlNodeType.ConstructorParameterType: XamlConstructorParameterTypeNode xamlConstructorParameterTypeNode = (XamlConstructorParameterTypeNode)xamlNode; WriteConstructorParameterType(xamlConstructorParameterTypeNode); break; default: Debug.Assert(false,"Unknown Xaml Token."); break; } } #endregion // PublicMethods #region Virtuals ////// Called when parsing begins /// public virtual void WriteDocumentStart(XamlDocumentStartNode XamlDocumentStartNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WriteDocumentStart(XamlDocumentStartNode); } } ////// Called when parsing ends /// public virtual void WriteDocumentEnd(XamlDocumentEndNode xamlEndDocumentNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WriteDocumentEnd(xamlEndDocumentNode); } } ////// Write Start of an Element, which is a tag of the form / public virtual void WriteElementStart(XamlElementStartNode xamlElementStartNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WriteElementStart(xamlElementStartNode); } } ////// /// Write start of an unknown tag /// public virtual void WriteUnknownTagStart(XamlUnknownTagStartNode xamlUnknownTagStartNode) { // The default action for unknown tags is throw an exception. ThrowException(SRID.ParserUnknownTag , xamlUnknownTagStartNode.Value, xamlUnknownTagStartNode.XmlNamespace, xamlUnknownTagStartNode.LineNumber, xamlUnknownTagStartNode.LinePosition); } ////// Write end of an unknown tag /// public virtual void WriteUnknownTagEnd(XamlUnknownTagEndNode xamlUnknownTagEndNode) { // The default action for unknown tags is throw an exception. This should never // get here unless there is a coding error, since it would first hit // WriteUnknownTagStart ThrowException(SRID.ParserUnknownTag , "???", xamlUnknownTagEndNode.LineNumber, xamlUnknownTagEndNode.LinePosition); } ////// Write End Element /// public virtual void WriteElementEnd(XamlElementEndNode xamlElementEndNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WriteElementEnd(xamlElementEndNode); } } ////// Called when parsing hits literal content. /// public virtual void WriteLiteralContent(XamlLiteralContentNode xamlLiteralContentNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WriteLiteralContent(xamlLiteralContentNode); } } ////// Write Start Complex Property, where the tag is of the /// form / public virtual void WritePropertyComplexStart( XamlPropertyComplexStartNode xamlPropertyComplexStartNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WritePropertyComplexStart(xamlPropertyComplexStartNode); } } ////// /// Write End Complex Property /// public virtual void WritePropertyComplexEnd( XamlPropertyComplexEndNode xamlPropertyComplexEndNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WritePropertyComplexEnd(xamlPropertyComplexEndNode); } } ////// Write Start element for a dictionary key section. /// public virtual void WriteKeyElementStart( XamlElementStartNode xamlKeyElementStartNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WriteKeyElementStart(xamlKeyElementStartNode); } } ////// Write End element for a dictionary key section /// public virtual void WriteKeyElementEnd( XamlElementEndNode xamlKeyElementEndNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WriteKeyElementEnd(xamlKeyElementEndNode); } } ////// Write unknown attribute /// public virtual void WriteUnknownAttribute(XamlUnknownAttributeNode xamlUnknownAttributeNode) { // The default action for unknown attributes is throw an exception. ThrowException(SRID.ParserUnknownAttribute , xamlUnknownAttributeNode.Name, xamlUnknownAttributeNode.XmlNamespace, xamlUnknownAttributeNode.LineNumber, xamlUnknownAttributeNode.LinePosition); } ////// Write a Property, which has the form in markup of property="value". /// ////// Note that for DependencyProperties, the assemblyName, TypeFullName, PropIdName /// refer to DependencyProperty field /// that the property was found on. This may be different from the ownerType /// of the propId if the property was registered as an alias so if the /// callback is persisting we want to persist the information that the propId /// was found on in case the alias is a private or internal field. /// public virtual void WriteProperty(XamlPropertyNode xamlPropertyNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WriteProperty(xamlPropertyNode); } } internal void WriteBaseProperty(XamlPropertyNode xamlPropertyNode) { if (BamlRecordWriter != null) { BamlRecordWriter.BaseWriteProperty(xamlPropertyNode); } } ////// Write a Property, which has the form in markup of property="value". /// ////// Note that for DependencyProperties, the assemblyName, TypeFullName, PropIdName /// refer to DependencyProperty field /// that the property was found on. This may be different from the ownerType /// of the propId if the property was registered as an alias so if the /// callback is persisting we want to persist the information that the propId /// was found on in case the alias is a private or internal field. /// public virtual void WritePropertyWithType(XamlPropertyWithTypeNode xamlPropertyNode) { if (BamlRecordWriter != null) { if (xamlPropertyNode.ValueElementType == null) { ThrowException(SRID.ParserNoType, xamlPropertyNode.ValueTypeFullName, xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition); } BamlRecordWriter.WritePropertyWithType(xamlPropertyNode); } } public virtual void WritePropertyWithExtension(XamlPropertyWithExtensionNode xamlPropertyWithExtensionNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WritePropertyWithExtension(xamlPropertyWithExtensionNode); } } ////// Write out Text, currently don't keep track if originally CData or Text /// public virtual void WriteText(XamlTextNode xamlTextNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WriteText(xamlTextNode); } } ////// Write a new namespacePrefix to NamespaceURI map /// public virtual void WriteNamespacePrefix(XamlXmlnsPropertyNode xamlXmlnsPropertyNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WriteNamespacePrefix(xamlXmlnsPropertyNode); } } ////// Xml - Clr namespace mapping /// public virtual void WritePIMapping(XamlPIMappingNode xamlPIMappingNode) { // The only case when the assembly name can be empty is when there is a local assembly // specified in the Mapping PI, but the compiler extension should have resolved it by // now. So if we are still seeing an empty string here that means we in the pure xaml // parsing scenario and should throw. if (xamlPIMappingNode.AssemblyName.Length == 0) { ThrowException(SRID.ParserMapPIMissingKey, xamlPIMappingNode.LineNumber, xamlPIMappingNode.LinePosition); } if (BamlRecordWriter != null) { BamlRecordWriter.WritePIMapping(xamlPIMappingNode); } } ////// Write out the Clr event. /// public virtual void WriteClrEvent(XamlClrEventNode xamlClrEventNode) { // Parser currently doesn't support hooking up Events directly from // XAML so throw an exception. In the compile case this method // is overriden. if (null == ParserHooks) { ThrowException(SRID.ParserNoEvents, xamlClrEventNode.LineNumber, xamlClrEventNode.LinePosition); } else if (BamlRecordWriter != null) { BamlRecordWriter.WriteClrEvent(xamlClrEventNode); } } ////// Write Property Array Start /// public virtual void WritePropertyArrayStart(XamlPropertyArrayStartNode xamlPropertyArrayStartNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WritePropertyArrayStart(xamlPropertyArrayStartNode); } } ////// Write Property Array End /// public virtual void WritePropertyArrayEnd(XamlPropertyArrayEndNode xamlPropertyArrayEndNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WritePropertyArrayEnd(xamlPropertyArrayEndNode); } } ////// Write Property IList Start /// public virtual void WritePropertyIListStart(XamlPropertyIListStartNode xamlPropertyIListStartNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WritePropertyIListStart(xamlPropertyIListStartNode); } } ////// Write Property IList End /// public virtual void WritePropertyIListEnd(XamlPropertyIListEndNode xamlPropertyIListEndNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WritePropertyIListEnd(xamlPropertyIListEndNode); } } ////// Write Property IDictionary Start /// public virtual void WritePropertyIDictionaryStart(XamlPropertyIDictionaryStartNode xamlPropertyIDictionaryStartNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WritePropertyIDictionaryStart(xamlPropertyIDictionaryStartNode); } } ////// Write Property IDictionary End /// public virtual void WritePropertyIDictionaryEnd(XamlPropertyIDictionaryEndNode xamlPropertyIDictionaryEndNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WritePropertyIDictionaryEnd(xamlPropertyIDictionaryEndNode); } } ////// WriteEndAttributes occurs after the last attribute (property, complex property or /// def record) is written. Note that if there are none of the above, then WriteEndAttributes /// is not called for a normal start tag. /// public virtual void WriteEndAttributes(XamlEndAttributesNode xamlEndAttributesNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WriteEndAttributes(xamlEndAttributesNode); } } ////// WriteDefTag occurs when a x:Whatever tag is encountered. /// Superclasses must interprete this since the base class doesn't understand /// any of them. /// public virtual void WriteDefTag(XamlDefTagNode xamlDefTagNode) { ThrowException(SRID.ParserDefTag, xamlDefTagNode.Value, xamlDefTagNode.LineNumber, xamlDefTagNode.LinePosition); } ////// Write out a key to a dictionary that has been resolved at compile or parse /// time to a Type object. /// public virtual void WriteDefAttributeKeyType(XamlDefAttributeKeyTypeNode xamlDefNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WriteDefAttributeKeyType(xamlDefNode); } } ////// WriteDefAttribute when attributes of the form x:Whatever are encountered /// public virtual void WriteDefAttribute(XamlDefAttributeNode xamlDefAttributeNode) { string attributeValue = xamlDefAttributeNode.Value; // There are several known def attributes, and these are checked for // correctness by running the known type converters. switch(xamlDefAttributeNode.Name) { case XamlReaderHelper.DefinitionSynchronousMode: if (BamlRecordWriter != null) { if (xamlDefAttributeNode.Value == "Async") { ThrowException(SRID.ParserNoBamlAsync, "Async", xamlDefAttributeNode.LineNumber, xamlDefAttributeNode.LinePosition); } } break; case XamlReaderHelper.DefinitionAsyncRecords: // Update the AsyncRecords and don't store this as a def attribute ThrowException(SRID.ParserNoBamlAsync, xamlDefAttributeNode.Name, xamlDefAttributeNode.LineNumber, xamlDefAttributeNode.LinePosition); break; case XamlReaderHelper.DefinitionShared: Boolean.Parse(attributeValue); // For validation only. if (BamlRecordWriter != null) { BamlRecordWriter.WriteDefAttribute(xamlDefAttributeNode); } break; case XamlReaderHelper.DefinitionUid: case XamlReaderHelper.DefinitionRuntimeName: //Error if x:Uid or x:Name are markup extensions if (MarkupExtensionParser.LooksLikeAMarkupExtension(attributeValue)) { string message = SR.Get(SRID.ParserBadUidOrNameME, attributeValue); message += " "; message += SR.Get(SRID.ParserLineAndOffset, xamlDefAttributeNode.LineNumber.ToString(CultureInfo.CurrentCulture), xamlDefAttributeNode.LinePosition.ToString(CultureInfo.CurrentCulture)); XamlParseException parseException = new XamlParseException(message, xamlDefAttributeNode.LineNumber, xamlDefAttributeNode.LinePosition); throw parseException; } if (BamlRecordWriter != null) { BamlRecordWriter.WriteDefAttribute(xamlDefAttributeNode); } break; case XamlReaderHelper.DefinitionName: if (BamlRecordWriter != null) { BamlRecordWriter.WriteDefAttribute(xamlDefAttributeNode); } break; default: string errorID; errorID = SRID.ParserUnknownDefAttribute; ThrowException(errorID, xamlDefAttributeNode.Name, xamlDefAttributeNode.LineNumber, xamlDefAttributeNode.LinePosition); break; } } ////// Write attributes of the form PresentationOptions:Whatever to Baml /// public virtual void WritePresentationOptionsAttribute(XamlPresentationOptionsAttributeNode xamlPresentationOptionsAttributeNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WritePresentationOptionsAttribute(xamlPresentationOptionsAttributeNode); } } ////// Write the start of a constructor parameter section /// public virtual void WriteConstructorParametersStart(XamlConstructorParametersStartNode xamlConstructorParametersStartNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WriteConstructorParametersStart(xamlConstructorParametersStartNode); } } public virtual void WriteContentProperty(XamlContentPropertyNode xamlContentPropertyNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WriteContentProperty(xamlContentPropertyNode); } } ////// Write the constructor parameter record where the parameter is a compile time /// resolved Type object. /// public virtual void WriteConstructorParameterType( XamlConstructorParameterTypeNode xamlConstructorParameterTypeNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WriteConstructorParameterType(xamlConstructorParameterTypeNode); } } ////// Write the end of a constructor parameter section /// public virtual void WriteConstructorParametersEnd(XamlConstructorParametersEndNode xamlConstructorParametersEndNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WriteConstructorParametersEnd(xamlConstructorParametersEndNode); } } ////// Can be used by ac to return the type of the element if a class attribute is /// present. If want to override default Type because of class= attribute can do so here. /// Should leave the XmlReader positioned at the Element so if read attributes /// to determine type need to call XmlReader.MoveToElement() /// public virtual bool GetElementType( XmlReader reader, string localName, string namespaceUri, ref string assemblyName, ref string typeFullName, ref Type baseType, ref Type serializerType) { bool result = false; assemblyName = string.Empty; typeFullName = string.Empty; serializerType = null; baseType = null; // if no namespaceURI or local name don't bother if (null == namespaceUri || null == localName) { return false; } TypeAndSerializer typeAndSerializer = XamlTypeMapper.GetTypeAndSerializer(namespaceUri, localName, null); if (typeAndSerializer != null && typeAndSerializer.ObjectType != null) { serializerType = typeAndSerializer.SerializerType; baseType = typeAndSerializer.ObjectType; typeFullName = baseType.FullName; assemblyName = baseType.Assembly.FullName; result = true; Debug.Assert(null != assemblyName, "assembly name returned from GetBaseElement is null"); Debug.Assert(null != typeFullName, "Type name returned from GetBaseElement is null"); } return result; } #endregion Virtuals ////// Write a Connector Id for compiler. /// protected internal void WriteConnectionId(Int32 connectionId) { if (BamlRecordWriter != null) { BamlRecordWriter.WriteConnectionId(connectionId); } } ////// A def attribute was encountered. Perform synchonous mode checking /// prior to calling the virtual that may be overridden. /// void WriteDefAttributeCore(XamlDefAttributeNode xamlDefAttributeNode) { string attributeValue = xamlDefAttributeNode.Value; switch(xamlDefAttributeNode.Name) { case XamlReaderHelper.DefinitionSynchronousMode: XamlParseMode documentParseMode = XamlParseMode.Synchronous; if (attributeValue.Equals("Async")) { documentParseMode = XamlParseMode.Asynchronous; } else if (attributeValue.Equals("[....]")) { documentParseMode = XamlParseMode.Synchronous; } else { ThrowException(SRID.ParserBadSyncMode, xamlDefAttributeNode.LineNumber, xamlDefAttributeNode.LinePosition ); } // if we haven't initialized the the parseMode yet set it if (XamlParseMode == XamlParseMode.Uninitialized) { // todo: for now hardcode the string. when finalized // should add a TypeConverter. XamlParseMode = documentParseMode; } break; default: break; } WriteDefAttribute(xamlDefAttributeNode); } #region Methods // virtuals to override the default implementation. used by the compiler // for internal virtuals review why not public as the others? // Used when an exception is thrown.The default action is to shutdown the parser // and throw the exception. internal virtual void ParseError(XamlParseException e) { } ////// Called when the parse was cancelled by the user. /// internal virtual void ParseCancelled() { } ////// called when the parse has been completed successfully. /// internal virtual void ParseCompleted() { } ////// Default parsing is to synchronously read all the xaml nodes /// until done. /// internal virtual void _Parse() { ReadXaml(false /* want to parse the entire thing */); } ////// If there are ParserHooks, call it with the current xamlNode and perform /// as directed by the callback. /// private void SetParserAction(XamlNode xamlNode) { // if no ParserHooks then process as normal if (null == ParserHooks) { ParserAction = ParserAction.Normal; return; } // if ParserHooks want to skip the current node and its children, // check for end of scope where it asked to be skipped. if (ParserAction == ParserAction.Skip) { if (xamlNode.Depth <= SkipActionDepthCount && xamlNode.TokenType == SkipActionToken) { // We found the end token at the correct depth. Reset the depth count // so that in the next call we won't skip calling the ParserHooks. Don't // reset the ParserAction since we want to skip this end token. SkipActionDepthCount = -1; SkipActionToken = XamlNodeType.Unknown; return; } else if (SkipActionDepthCount >= 0) { return; } } // If we get to here, the ParserHooks want to be called. ParserAction = ParserHooks.LoadNode(xamlNode); // if the ParserHooks want to skip the current node and its children then // set the callback depth so that we'll know when to start processing again. if (ParserAction == ParserAction.Skip) { // For tokens with no scope (eg = attributes), don't set the depth so // that we will only skip once Debug.Assert(SkipActionDepthCount == -1); int tokenIndex = ((IList)XamlNode.ScopeStartTokens).IndexOf(xamlNode.TokenType); if (tokenIndex != -1) { SkipActionDepthCount = xamlNode.Depth; SkipActionToken = XamlNode.ScopeEndTokens[tokenIndex]; } } } // Return true if the passed namespace is known, meaning that it maps // to a set of assemblies and clr namespaces internal bool IsXmlNamespaceSupported(string xmlNamespace, out string newXmlNamespace) { newXmlNamespace = null; if (xmlNamespace.StartsWith(XamlReaderHelper.MappingProtocol, StringComparison.Ordinal)) { return true; } else if (xmlNamespace == XamlReaderHelper.PresentationOptionsNamespaceURI) { // PresentationOptions is expected to be marked as 'ignorable' in most Xaml // so that other Xaml parsers don't have to interpret it, but this parser // does handle it to support it's Freeze attribute. return true; } else { return XamlTypeMapper.IsXmlNamespaceKnown(xmlNamespace, out newXmlNamespace) || TokenReader.IsXmlDataIsland(); } } #endregion Methods #region Properties ////// TokenReader that is being used. /// internal XamlReaderHelper TokenReader { get { return _xamlTokenReader; } set { _xamlTokenReader = value; } } ////// ParserHooks implementation that any parse time callbacks /// should be called on. /// internal ParserHooks ParserHooks { get { return _parserHooks; } set { _parserHooks = value; } } // Set the depth count for how deep we are within // a ParserAction.Skip reference. int SkipActionDepthCount { get { return _skipActionDepthCount; } set { _skipActionDepthCount = value; } } // Set and get the token to watch for when skipping a // section of a xaml file XamlNodeType SkipActionToken { get { return _skipActionToken; } set { _skipActionToken = value; } } // set the operation mode of the parser as determined // by attached ParserHooks ParserAction ParserAction { get { return _parserAction; } set { _parserAction = value; } } ////// Instance of the XamlTypeMapper /// internal XamlTypeMapper XamlTypeMapper { get { return _parserContext.XamlTypeMapper; } } ////// Instance of the BamlMapTable /// internal BamlMapTable MapTable { get { return _parserContext.MapTable; } } ////// BamlRecordWriter being used by the Parser /// public BamlRecordWriter BamlRecordWriter { get { return _bamlWriter; } set { Debug.Assert(null == _bamlWriter || null == value, "XamlParser already had a bamlWriter"); _bamlWriter = value; } } ////// ParseMode the Parser is in. /// internal XamlParseMode XamlParseMode { get { return _xamlParseMode; } set { _xamlParseMode = value; } } ////// Parser context /// internal ParserContext ParserContext { get { return _parserContext; } set { _parserContext = value; } } internal virtual bool CanResolveLocalAssemblies() { return false; } // Used to determine if strict or loose parsing rules should be enforced. The TokenReader // does some validations that are difficult for the XamlParser to do and in strict parsing // mode the TokenReader should throw exceptions of standard Xaml rules are violated. internal virtual bool StrictParsing { get { return true; } } #endregion Properties #region Data // private Data XamlReaderHelper _xamlTokenReader; ParserContext _parserContext; // todo, need this for the XamlTypeMapper/resolver. XamlParseMode _xamlParseMode; BamlRecordWriter _bamlWriter; // ParserHooks related ParserHooks _parserHooks; ParserAction _parserAction = ParserAction.Normal; int _skipActionDepthCount = -1; // skip mode depth count. XamlNodeType _skipActionToken = XamlNodeType.Unknown; static private string [] _predefinedNamespaces = new string [3] { XamlReaderHelper.DefinitionNamespaceURI, XamlReaderHelper.DefaultNamespaceURI, XamlReaderHelper.DefinitionMetroNamespaceURI }; #endregion Data #endif // helper method called to throw an exception. // todo: update exception with lineNumbers from Node. internal static void ThrowException(string id, int lineNumber, int linePosition) { string message = SR.Get(id); ThrowExceptionWithLine(message, lineNumber, linePosition); } // helper method called to throw an exception. internal static void ThrowException(string id, string value, int lineNumber, int linePosition) { string message = SR.Get(id, value); ThrowExceptionWithLine(message, lineNumber, linePosition); } // helper method called to throw an exception. internal static void ThrowException(string id, string value1, string value2, int lineNumber, int linePosition) { string message = SR.Get(id, value1, value2); ThrowExceptionWithLine(message, lineNumber, linePosition); } internal static void ThrowException(string id, string value1, string value2, string value3, int lineNumber, int linePosition) { string message = SR.Get(id, value1, value2, value3); ThrowExceptionWithLine(message, lineNumber, linePosition); } internal static void ThrowException(string id, string value1, string value2, string value3, string value4, int lineNumber, int linePosition) { string message = SR.Get(id, value1, value2, value3, value4); ThrowExceptionWithLine(message, lineNumber, linePosition); } private static void ThrowExceptionWithLine(string message, int lineNumber, int linePosition) { message += " "; message += SR.Get(SRID.ParserLineAndOffset, lineNumber.ToString(CultureInfo.CurrentCulture), linePosition.ToString(CultureInfo.CurrentCulture)); XamlParseException parseException = new XamlParseException(message, lineNumber, linePosition); throw parseException; } } } // 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
- ScaleTransform3D.cs
- mediaclock.cs
- FixedPageProcessor.cs
- ObfuscateAssemblyAttribute.cs
- TextReader.cs
- PartitionerQueryOperator.cs
- mactripleDES.cs
- SubMenuStyle.cs
- CodeMemberField.cs
- MetadataCollection.cs
- Viewport3DAutomationPeer.cs
- PatternMatchRules.cs
- Win32MouseDevice.cs
- JpegBitmapDecoder.cs
- InstanceHandle.cs
- ToolStripGripRenderEventArgs.cs
- AccessControlList.cs
- MetadataSource.cs
- SerializationTrace.cs
- RouteParameter.cs
- SoapExtensionStream.cs
- RuleSettings.cs
- SplineQuaternionKeyFrame.cs
- WindowsPrincipal.cs
- MouseGestureConverter.cs
- EdmToObjectNamespaceMap.cs
- DBCommandBuilder.cs
- WebRequestModuleElement.cs
- NavigationEventArgs.cs
- altserialization.cs
- DefaultBindingPropertyAttribute.cs
- Substitution.cs
- ObjectDataSourceMethodEventArgs.cs
- GregorianCalendarHelper.cs
- SessionStateUtil.cs
- WebEncodingValidatorAttribute.cs
- RegionInfo.cs
- BasicHttpSecurityMode.cs
- NestedContainer.cs
- DynamicResourceExtensionConverter.cs
- TriggerActionCollection.cs
- NativeMethods.cs
- Accessible.cs
- LicenseException.cs
- PenCursorManager.cs
- AssemblyName.cs
- XmlMapping.cs
- ContentElementAutomationPeer.cs
- ContainerFilterService.cs
- BatchParser.cs
- CollectionsUtil.cs
- DataServiceBehavior.cs
- UIElementAutomationPeer.cs
- AttachInfo.cs
- InternalsVisibleToAttribute.cs
- TextBoxRenderer.cs
- ResourcePermissionBaseEntry.cs
- DocumentGridPage.cs
- CryptoHandle.cs
- TextServicesHost.cs
- Vector3DValueSerializer.cs
- CursorInteropHelper.cs
- GenericEnumConverter.cs
- UserMapPath.cs
- CompositeKey.cs
- Privilege.cs
- Profiler.cs
- X509Extension.cs
- AlgoModule.cs
- AttributeData.cs
- AlignmentXValidation.cs
- CompiledQuery.cs
- StringToken.cs
- DirectoryObjectSecurity.cs
- GradientBrush.cs
- TableRowCollection.cs
- ElementHostAutomationPeer.cs
- NameObjectCollectionBase.cs
- HttpCacheVary.cs
- SQLChars.cs
- BitmapEffect.cs
- initElementDictionary.cs
- Connector.xaml.cs
- ResourceAttributes.cs
- ExecutionEngineException.cs
- FloaterBaseParaClient.cs
- SafePEFileHandle.cs
- SoapInteropTypes.cs
- Number.cs
- ObjectCloneHelper.cs
- storepermission.cs
- Empty.cs
- TabControlDesigner.cs
- Transform3D.cs
- RemoveStoryboard.cs
- ClientSettingsSection.cs
- FolderBrowserDialogDesigner.cs
- XmlComplianceUtil.cs
- SharedDp.cs
- SqlTopReducer.cs