ParserContext.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

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

                            //---------------------------------------------------------------------------- 
//
// File: ParserContext.cs
//
// Description: 
//   class for the main TypeConverterContext object passed to type converters
// 
// 
// History:
//    8/02/01:    rogerg        Created 
//    05/23/03:   peterost      Ported to wcp
//    03/16/05:   chandras      Changed the XmlnsDictionary usage
//
// Copyright (C) 2001 by Microsoft Corporation.  All rights reserved. 
//
//--------------------------------------------------------------------------- 
 
using System;
using System.Reflection; 
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Xml; 
using MS.Utility;
using System.Diagnostics; 
 
#if PBTCOMPILER
using TCH = MS.Internal.Markup.TypeConverterHelper; 

namespace MS.Internal.Markup
#else
using System.Windows; 
using System.Security;
using MS.Internal; 
using TCH = System.Windows.Markup.TypeConverterHelper; 

namespace System.Windows.Markup 
#endif
{

#if PBTCOMPILER 

    /// 
    ///     The IUriContext interface allows elements (like Frame, PageViewer) and type converters 
    ///     (like BitmapImage TypeConverters) a way to ensure that base uri is set on them by the
    ///     parser, codegen for xaml, baml and caml cases.  The elements can then use this base uri 
    ///     to navigate.
    ///
    internal interface IUriContext
    { 
        /// 
        ///     Provides the base uri of the current context. 
        ///  
        Uri BaseUri
        { 
            get;
            set;
        }
    } 

#endif 
 
    /// 
    ///  Provides all the context information required by Parser 
    /// 
#if PBTCOMPILER
    internal class ParserContext : IUriContext
#else 
    public class ParserContext : IUriContext
#endif 
    { 

#region Public Methods 

        ///    
        ///    Constructor
        ///     
        public ParserContext()
        { 
            Initialize(); 
        }
 
        // Initialize the ParserContext to a known, default state.  DO NOT wipe out
        // data that may be able to be shared between seperate parses, such as the
        // xamlTypeMapper and the map table.
        internal void Initialize() 
        {
            _xmlnsDictionary = null;    // created on its first use 
#if !PBTCOMPILER 
            _nameScopeStack    = null;
#endif 
            _xmlLang        = String.Empty;
            _xmlSpace       = String.Empty;
        }
 

#if !PBTCOMPILER 
        ///  
        ///    Constructor that takes the XmlParserContext.
        ///    A parserContext object will be built based on this. 
        /// 
        /// xmlParserContext to use

        public ParserContext(XmlParserContext xmlParserContext) 
        {
            if (xmlParserContext == null) 
            { 
                throw new ArgumentNullException( "xmlParserContext" );
            } 

            _xmlLang     = xmlParserContext.XmlLang;

            TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof(XmlSpace)); 
            if (typeConverter != null)
                _xmlSpace = (string) typeConverter.ConvertToString(null, TCH.EnglishUSCulture, xmlParserContext.XmlSpace); 
            else 
                _xmlSpace = String.Empty;
 
            _xmlnsDictionary = new XmlnsDictionary() ;

            if (xmlParserContext.BaseURI != null && xmlParserContext.BaseURI.Length > 0)
            { 
                _baseUri = new Uri(xmlParserContext.BaseURI, UriKind.RelativeOrAbsolute);
            } 
 
            XmlNamespaceManager xmlnsManager = xmlParserContext.NamespaceManager;
 
            if (null != xmlnsManager)
            {
                foreach (string key in xmlnsManager)
                { 
                    _xmlnsDictionary.Add(key, xmlnsManager.LookupNamespace(key));
                } 
            } 
        }
#endif 

#if !PBTCOMPILER
        /// 
        /// Constructor overload that takes an XmlReader, in order to 
        /// pull the BaseURI, Lang, and Space from it.
        ///  
        internal ParserContext( XmlReader xmlReader ) 
        {
            if( xmlReader.BaseURI != null && xmlReader.BaseURI.Length != 0 ) 
            {
                BaseUri = new Uri( xmlReader.BaseURI );
            }
 
            XmlLang = xmlReader.XmlLang;
 
            if( xmlReader.XmlSpace != System.Xml.XmlSpace.None ) 
            {
                XmlSpace = xmlReader.XmlSpace.ToString(); 
            }
        }
#endif
 
#if !PBTCOMPILER
        ///  
        ///    Constructor that takes the ParserContext. 
        ///    A parserContext object will be built based on this.
        ///  
        /// xmlParserContext to use
        internal ParserContext(ParserContext parserContext)
        {
            _xmlLang     = parserContext.XmlLang; 
            _xmlSpace    = parserContext.XmlSpace;
            _xamlTypeMapper      = parserContext.XamlTypeMapper; 
            _mapTable    = parserContext.MapTable; 
            _baseUri     = parserContext.BaseUri;
 
            _rootElement = parserContext._rootElement;
            if (parserContext._nameScopeStack != null)
                _nameScopeStack = (Stack)parserContext._nameScopeStack.Clone();
            else 
                _nameScopeStack = null;
 
            // Don't want to force the lazy init so we just set privates 
            _skipJournaledProperties = parserContext._skipJournaledProperties;
 
            _xmlnsDictionary = null;

            // when there are no namespace prefix mappings in incoming ParserContext,
             // we are not going to create an empty XmlnsDictionary. 
            if (parserContext._xmlnsDictionary != null &&
                parserContext._xmlnsDictionary.Count > 0) 
            { 
                _xmlnsDictionary = new XmlnsDictionary();
 
                XmlnsDictionary xmlDictionaryFrom = parserContext.XmlnsDictionary;

                if (null != xmlDictionaryFrom)
                { 
                    foreach (string key in xmlDictionaryFrom.Keys)
                    { 
                        _xmlnsDictionary[key] = xmlDictionaryFrom[key]; 
                    }
                } 
            }
        }
#endif
 
        /// 
        /// Pushes the context scope stack (modifications to the ParserContext only apply to levels below 
        /// the modification in the stack, except for the XamlTypeMapper property) 
        /// 
        internal void PushScope() 
        {
            _repeat++;
            _currentFreezeStackFrame.IncrementRepeatCount();
 
            // Wait till the context needs XmlnsDictionary, create on first use.
            if (_xmlnsDictionary != null) 
                _xmlnsDictionary.PushScope(); 
        }
 
        /// 
        /// Pops the context scope stack
        /// 
        internal void PopScope() 
        {
            // Pop state off of the _langSpaceStack 
            if (_repeat > 0) 
            {
                _repeat--; 
            }
            else
            {
                if (null != _langSpaceStack && _langSpaceStack.Count > 0) 
                {
                    _repeat = (int) _langSpaceStack.Pop(); 
                    _targetType = (Type) _langSpaceStack.Pop(); 
                    _xmlSpace = (string) _langSpaceStack.Pop();
                    _xmlLang = (string) _langSpaceStack.Pop(); 
                }
            }

            // Pop state off of _currentFreezeStackFrame 
            if (!_currentFreezeStackFrame.DecrementRepeatCount())
            { 
                // If the end of the current frame has been reached, pop 
                // the next frame off the freeze stack
                _currentFreezeStackFrame = (FreezeStackFrame) _freezeStack.Pop(); 
            }

            // Wait till the context needs XmlnsDictionary, create on first use.
            if (_xmlnsDictionary != null) 
                _xmlnsDictionary.PopScope();
 
        } 

        ///  
        /// XmlNamespaceDictionary
        /// 
        public XmlnsDictionary  XmlnsDictionary
        { 
            get
            { 
                // Entry Point to others, initialize if null. 
                if (_xmlnsDictionary == null)
                    _xmlnsDictionary = new XmlnsDictionary(); 

                return _xmlnsDictionary;
            }
        } 

        ///  
        /// XmlLang property 
        /// 
        public string XmlLang 
        {
            get
            {
                return _xmlLang; 
            }
            set 
            { 
                EndRepeat();
                _xmlLang = (null == value ? String.Empty : value); 
            }
        }

        ///  
        /// XmlSpace property
        ///  
        // (Why isn't this of type XmlSpace?) 
        public string XmlSpace
        { 
            get
            {
                return _xmlSpace;
            } 
            set
            { 
                EndRepeat(); 
                _xmlSpace = value;
            } 
        }

        //
        // TargetType 
        //
        // Keep track of the Style/Template TargetType's in the current context.  This allows Setters etc 
        // to interpret properties without walking up the reader stack to see it.  This is internal and 
        // hard-coded to target type, but the intent in the future is to generalize this so that we don't
        // have to have the custom parser, and so that the designer can provide the same contextual information. 
        //
        internal Type TargetType
        {
            get 
            {
                return _targetType; 
            } 

#if !PBTCOMPILER 
            set
            {
                EndRepeat();
                _targetType = value; 
            }
#endif 
        } 

        // Items specific to XAML 

        /// 
        ///  XamlTypeMapper that should be used when resolving XML
        ///  
        public XamlTypeMapper XamlTypeMapper
        { 
            get 
            {
                return _xamlTypeMapper ; 
            }
            set
            {
                // The BamlMapTable must always be kept in [....] with the XamlTypeMapper.  If 
                // the XamlTypeMapper changes, then the map table must also be reset.
                if (_xamlTypeMapper != value) 
                { 
                    _xamlTypeMapper = value;
                    _mapTable = new BamlMapTable(value); 
                    _xamlTypeMapper.MapTable = _mapTable;
                }
            }
        } 
#if !PBTCOMPILER
        ///  
        ///  Gets or sets the list of INameScopes in parent chain 
        /// 
        internal Stack NameScopeStack 
        {
            get
            {
               if (_nameScopeStack == null) 
                   _nameScopeStack = new Stack(2);
 
               return _nameScopeStack; 
            }
        } 
#endif

        /// 
        ///    Gets or sets the base Uri 
        /// 
        public Uri BaseUri 
        { 
            get
            { 
                return _baseUri ;
            }
            set
            { 
                _baseUri = value;
            } 
        } 

#if !PBTCOMPILER 
        /// 
        /// Should DependencyProperties marked with the Journal metadata flag be set or skipped?
        /// 
        ///  
        internal bool SkipJournaledProperties
        { 
            get { return _skipJournaledProperties; } 
            set { _skipJournaledProperties = value; }
        } 

        //
        // The Assembly which hosts the Baml stream.
        // 
        /// 
        ///     Critical - because it sets the value of the _streamCreatedAssembly field, and that is 
        ///                SecurityCritical Data as this field is used by the BamlRecordReader to 
        ///                allow legitimate internal types in Partial Trust.
        ///  
        internal Assembly StreamCreatedAssembly
        {
            get { return _streamCreatedAssembly.Value; }
 
            [SecurityCritical]
            set { _streamCreatedAssembly.Value = value; } 
        } 
#endif
 
        /// 
        ///    Operator for Converting a ParserContext to an XmlParserContext
        /// 
        /// ParserContext to Convert 
        /// XmlParserContext
        public static implicit operator XmlParserContext(ParserContext parserContext) 
        { 
            return ParserContext.ToXmlParserContext(parserContext);
        } 


        /// 
        ///    Operator for Converting a ParserContext to an XmlParserContext 
        /// 
        /// ParserContext to Convert 
        /// XmlParserContext 
        public static XmlParserContext ToXmlParserContext(ParserContext parserContext)
        { 
            if (parserContext == null)
            {
                throw new ArgumentNullException( "parserContext" );
            } 

            XmlNamespaceManager xmlnsMgr = new XmlNamespaceManager(new NameTable()); 
            XmlSpace xmlSpace = System.Xml.XmlSpace.None; 

            if (parserContext.XmlSpace != null && parserContext.XmlSpace.Length != 0) 
            {
                TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof(System.Xml.XmlSpace));
                if (null != typeConverter)
                { 
                    try
                    { 
                        xmlSpace = (System.Xml.XmlSpace)typeConverter.ConvertFromString(null, TCH.EnglishUSCulture, parserContext.XmlSpace); 
                    }
                    catch (System.FormatException)  // If it's not a valid space value, ignore it 
                    {
                        xmlSpace = System.Xml.XmlSpace.None;
                    }
                } 
            }
 
            // We start getting Keys list only if we have non-empty dictionary 

            if (parserContext._xmlnsDictionary != null) 
            {
                foreach (string key in parserContext._xmlnsDictionary.Keys)
                {
                    xmlnsMgr.AddNamespace(key, parserContext._xmlnsDictionary[key]); 
                }
            } 
 
            XmlParserContext xmlParserContext = new XmlParserContext(null, xmlnsMgr, parserContext.XmlLang, xmlSpace);
            if( parserContext.BaseUri == null) 
            {
                xmlParserContext.BaseURI = null;
            }
            else 
            {
                string serializedSafe = parserContext.BaseUri.GetComponents(UriComponents.SerializationInfoString, UriFormat.SafeUnescaped); 
                Uri sameUri = new Uri(serializedSafe); 
                string cannonicalString =  sameUri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped);
                xmlParserContext.BaseURI = cannonicalString; 
            }

            return xmlParserContext;
        } 

#endregion Public Methods 
 
#region Internal
 

        // Reset stack to default state
        private void EndRepeat()
        { 
            if (_repeat > 0)
            { 
                if (null == _langSpaceStack) 
                {
                    _langSpaceStack = new Stack(1); 
                }

                _langSpaceStack.Push(XmlLang);
                _langSpaceStack.Push(XmlSpace); 
                _langSpaceStack.Push(TargetType);
                _langSpaceStack.Push(_repeat); 
                _repeat = 0; 
            }
        } 

        /// 
        /// LineNumber for the first character in the given
        /// stream. This is used when parsing a section of a larger file so 
        /// that proper line number in the overall file can be calculated.
        ///  
        internal int LineNumber 
        {
            get { return _lineNumber; } 
#if !PBTCOMPILER
            set { _lineNumber = value; }
#endif
        } 

 
        ///  
        /// LinePosition for the first character in the given
        /// stream. This is used when parsing a section of a larger file so 
        /// that proper line positions in the overall file can be calculated.
        /// 
        internal int LinePosition
        { 
            get { return _linePosition; }
#if !PBTCOMPILER 
            set { _linePosition = value; } 
#endif
        } 

#if !PBTCOMPILER
        internal bool IsDebugBamlStream
        { 
            get { return _isDebugBamlStream; }
            set { _isDebugBamlStream = value; } 
        } 

        ///  
        /// Gets or sets the object at the root of the portion of the tree
        /// currently being parsed.  Note that this may not be the very top of the tree
        /// if the parsing operation is scoped to a specific subtree, such as in Style
        /// parsing. 
        /// 
        internal object RootElement 
        { 
            get { return _rootElement; }
            set { _rootElement = value; } 
        }

        // If this is false (default), then the parser does not own the stream and so if
        // it has any defer loaded content, it needs to copy it into a byte array since 
        // the owner\caller will close the stream when parsing is complete. Currently, this
        // is set to true only by the theme engine since the stream is a system-wide resource 
        // an dso will always be open for teh lifetime of the process laoding the theme and so 
        // it can be re-used for perf reasons.
        internal bool OwnsBamlStream 
        {
            get { return _ownsBamlStream; }
            set { _ownsBamlStream = value; }
        } 
#endif
 
        ///  
        /// Allows sharing a map table between instances of BamlReaders and Writers.
        ///  

        internal BamlMapTable MapTable
        {
            get { return _mapTable; } 
#if !PBTCOMPILER
            set 
            { 
                // The XamlTypeMapper and the map table must always be kept in [....].  If the
                // map table changes, update the XamlTypeMapper also 
                if (_mapTable != value)
                {
                    _mapTable = value;
                    _xamlTypeMapper = _mapTable.XamlTypeMapper; 
                    _xamlTypeMapper.MapTable = _mapTable;
                } 
            } 
#endif
        } 

#if !PBTCOMPILER

        ///  
        ///  Allows accessing the associated BamlRecordReader for doing custom processing
        ///  and searches of the reader stack during parse time. 
        ///  
        internal BamlRecordReader BamlReader
        { 
            get { return _bamlRecordReader; }
            set { _bamlRecordReader = value; }
        }
 

        internal IStyleConnector StyleConnector 
        { 
            get { return _styleConnector; }
            set { _styleConnector = value; } 
        }

        // Keep a cached ProvideValueProvider so that we don't have to keep re-creating one.
        internal ProvideValueServiceProvider ProvideValueProvider 
        {
            get 
            { 
                if (_provideValueServiceProvider == null)
                { 
                    _provideValueServiceProvider = new ProvideValueServiceProvider(this);
                }

                return _provideValueServiceProvider; 
            }
        } 
 
        /// 
        /// This is used to resolve a StaticResourceId record within a deferred content 
        /// section against a StaticResourceExtension on the parent dictionary.
        /// 
        internal List StaticResourcesStack
        { 
            get
            { 
                if (_staticResourcesStack == null) 
                {
                    _staticResourcesStack = new List(); 
                }

                return _staticResourcesStack;
            } 
        }
 
        ///  
        /// Says if we are we currently loading deferred content
        ///  
        internal bool InDeferredSection
        {
            get { return (_staticResourcesStack != null && _staticResourcesStack.Count > 0); }
        } 
#endif
 
        // Return a new Parser context that has the same instance variables as this instance, with 
        // only scope dependent variables deep copied.  Variables that are not dependent on scope
        // (such as the baml map table) are not deep copied. 

#if !PBTCOMPILER
        internal ParserContext ScopedCopy()
        { 
            return ScopedCopy( true /* copyNameScopeStack */ );
        } 
#endif 

#if !PBTCOMPILER 
        /// 
        ///     Critical - because it sets _streamCreatedAssembly on the ParserContext, and that is
        ///                SecurityCritical Data as this field is used by the BamlRecordReader to
        ///                allow legitimate internal types in Partial Trust. 
        ///     Safe - because it gets this value from a copy of itself that gets it from a stream that
        ///            implements an internal IStreamInfo interface and IStreamInfo.Assembly is set\ 
        ///            by the ResourceContainer code that is SecurityCritical, but treated as safe. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal ParserContext ScopedCopy(bool copyNameScopeStack)
        {
            ParserContext context = new ParserContext();
 
            context._baseUri = _baseUri;
            context._skipJournaledProperties = _skipJournaledProperties; 
            context._xmlLang = _xmlLang; 
            context._xmlSpace = _xmlSpace;
            context._repeat = _repeat; 
            context._lineNumber = _lineNumber;
            context._linePosition = _linePosition;
            context._isDebugBamlStream = _isDebugBamlStream;
            context._mapTable = _mapTable; 
            context._xamlTypeMapper = _xamlTypeMapper;
            context._targetType = _targetType; 
 
            context._streamCreatedAssembly.Value = _streamCreatedAssembly.Value;
            context._rootElement = _rootElement; 
            context._styleConnector = _styleConnector;

            // Copy the name scope stack, if necessary.
 
            if (_nameScopeStack != null && copyNameScopeStack)
                context._nameScopeStack = (_nameScopeStack != null) ? (Stack)_nameScopeStack.Clone() : null; 
            else 
                context._nameScopeStack = null;
 
            // Deep copy only selected scope dependent instance variables
            context._langSpaceStack = (_langSpaceStack != null) ? (Stack)_langSpaceStack.Clone() : null;

            if (_xmlnsDictionary != null) 
                context._xmlnsDictionary = new XmlnsDictionary(_xmlnsDictionary);
            else 
                context._xmlnsDictionary = null; 

            context._currentFreezeStackFrame = _currentFreezeStackFrame; 
            context._freezeStack = (_freezeStack != null) ? (Stack) _freezeStack.Clone() : null;

            return context;
        } 
#endif
 
        // 
        // This is called by a user of a parser context when it is a good time to drop unnecessary
        // references (today, just an empty stack). 
        //

#if !PBTCOMPILER
        internal void TrimState() 
        {
 
                if( _nameScopeStack != null && _nameScopeStack.Count == 0 ) 
                {
                    _nameScopeStack = null; 
                }

        }
#endif 

        // Return a new Parser context that has the same instance variables as this instance, 
        // will all scoped and non-scoped complex properties deep copied. 
#if !PBTCOMPILER
        internal ParserContext Clone() 
        {
            ParserContext context = ScopedCopy();

            // Deep copy only selected instance variables 
            context._mapTable = (_mapTable != null) ? _mapTable.Clone() : null;
            context._xamlTypeMapper = (_xamlTypeMapper != null) ? _xamlTypeMapper.Clone() : null; 
 
            // Connect the XamlTypeMapper and bamlmaptable
            context._xamlTypeMapper.MapTable = context._mapTable; 
            context._mapTable.XamlTypeMapper = context._xamlTypeMapper;

            return context;
        } 
#endif
 
#if !PBTCOMPILER 
        // Set/Get whether or not Freezables within the current scope
        // should be Frozen. 
        internal bool FreezeFreezables
        {
            get
            { 
                return _currentFreezeStackFrame.FreezeFreezables;
            } 
 
            set
            { 
                // If the freeze flag isn't actually changing, we don't need to
                // register a change
                if (value != _currentFreezeStackFrame.FreezeFreezables)
                { 
                    // When this scope was entered the repeat count was initially incremented,
                    // indicating no _freezeFreezables state changes within this scope. 
                    // 
                    // Now that a state change has been found, we need to replace that no-op with
                    // a directive to restore the old state by un-doing the increment 
                    // and pushing the stack frame
#if DEBUG
                    bool canDecrement =
#endif 
                    _currentFreezeStackFrame.DecrementRepeatCount();
#if DEBUG 
                    // We're replacing a no-op with a state change.  Detect if we accidently 
                    // start replacing actual state changes.  This might happen if we allowed
                    // FreezeFreezable to be set twice within the same scope, for 
                    // example.
                    Debug.Assert(canDecrement);
#endif
                    if (_freezeStack == null) 
                    {
                        // Lazily allocate a _freezeStack if this is the first 
                        // state change. 
                        _freezeStack = new Stack();
                    } 

                    // Save the old frame
                    _freezeStack.Push(_currentFreezeStackFrame);
 
                    // Set the new frame
                    _currentFreezeStackFrame.Reset(value); 
                } 
            }
        } 

        internal bool TryCacheFreezable(string value, Freezable freezable)
        {
            if (FreezeFreezables) 
            {
                if (freezable.CanFreeze) 
                { 
                    if (!freezable.IsFrozen)
                    { 
                        freezable.Freeze();
                    }
                    if (_freezeCache == null)
                    { 
                        _freezeCache = new Dictionary();
                    } 
                    _freezeCache.Add(value, freezable); 
                    return true;
                } 
            }

            return false;
        } 

        internal Freezable TryGetFreezable(string value) 
        { 
            Freezable freezable = null;
            if (_freezeCache != null) 
            {
                _freezeCache.TryGetValue(value, out freezable);
            }
 
            return freezable;
        } 
#endif 

#endregion Internal 

#region Date

        private XamlTypeMapper          _xamlTypeMapper; 
        private Uri                     _baseUri;
 
        private XmlnsDictionary         _xmlnsDictionary; 
        private String                  _xmlLang        = String.Empty;
        private String                  _xmlSpace       = String.Empty; 
        private Stack                   _langSpaceStack;
        private int                     _repeat;
        private Type                    _targetType;
 
#if !PBTCOMPILER
        private bool                    _skipJournaledProperties; 
        private SecurityCriticalDataForSet _streamCreatedAssembly; 
        private bool                    _ownsBamlStream;
        private ProvideValueServiceProvider _provideValueServiceProvider; 
        private IStyleConnector _styleConnector;
        private Stack                   _nameScopeStack;
        private BamlRecordReader        _bamlRecordReader;
        private List          _staticResourcesStack; 

        object                                      _rootElement;  // RootElement for the Page scoping [temporary, should be 
        // something like page name or baseUri] 

#endif 

        // Struct that maintains both the freezeFreezable state & stack depth
        // between freezeFreezable state changes
        private struct FreezeStackFrame 
        {
            internal void IncrementRepeatCount() { _repeatCount++; } 
 
            // Returns false when the count reaches 0 such that the decrement can not occur
            internal bool DecrementRepeatCount() 
            {
                if (_repeatCount > 0)
                {
                    _repeatCount--; 
                    return true;
                } 
                else 
                {
                    return false; 
                }
            }

#if !PBTCOMPILER 
            // Accessors for private state
            internal bool FreezeFreezables 
            { 
                get { return _freezeFreezables; }
            } 

            // Reset's this frame to a new scope.  Only used with _currentFreezeStackFrame.
            internal void Reset(bool freezeFreezables)
            { 
                _freezeFreezables = freezeFreezables;
                _repeatCount = 0; 
            } 

            // Whether or not Freezeables with the current scope should be Frozen 
            private bool _freezeFreezables;

#endif
 
            // The number of frames until the next state change.
            // We need to know how many times PopScope() is called until the 
            // state changes.  That information is tracked by _repeatCount. 
            private int _repeatCount;
        } 

        // First frame is maintained off of the _freezeStack to avoid allocating
        // a Stack for the common case where Freeze isn't specified.
        FreezeStackFrame _currentFreezeStackFrame; 

#if !PBTCOMPILER 
        // When cloning, it isn't necessary to copy this cache of freezables. 
        // This cache allows frozen freezables to use a shared instance and save on memory.
        private Dictionary _freezeCache; 
#endif

        private Stack _freezeStack = null;
 
        private int _lineNumber = 0;    // number of lines between the start of the file and
                                        // our starting point (the starting point of this context) 
        private int _linePosition=0;      // default start ot left of first character which is a zero 
        private BamlMapTable _mapTable;
#if !PBTCOMPILER 
        private bool _isDebugBamlStream = false;
#endif
#endregion Data
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------------------- 
//
// File: ParserContext.cs
//
// Description: 
//   class for the main TypeConverterContext object passed to type converters
// 
// 
// History:
//    8/02/01:    rogerg        Created 
//    05/23/03:   peterost      Ported to wcp
//    03/16/05:   chandras      Changed the XmlnsDictionary usage
//
// Copyright (C) 2001 by Microsoft Corporation.  All rights reserved. 
//
//--------------------------------------------------------------------------- 
 
using System;
using System.Reflection; 
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Xml; 
using MS.Utility;
using System.Diagnostics; 
 
#if PBTCOMPILER
using TCH = MS.Internal.Markup.TypeConverterHelper; 

namespace MS.Internal.Markup
#else
using System.Windows; 
using System.Security;
using MS.Internal; 
using TCH = System.Windows.Markup.TypeConverterHelper; 

namespace System.Windows.Markup 
#endif
{

#if PBTCOMPILER 

    /// 
    ///     The IUriContext interface allows elements (like Frame, PageViewer) and type converters 
    ///     (like BitmapImage TypeConverters) a way to ensure that base uri is set on them by the
    ///     parser, codegen for xaml, baml and caml cases.  The elements can then use this base uri 
    ///     to navigate.
    ///
    internal interface IUriContext
    { 
        /// 
        ///     Provides the base uri of the current context. 
        ///  
        Uri BaseUri
        { 
            get;
            set;
        }
    } 

#endif 
 
    /// 
    ///  Provides all the context information required by Parser 
    /// 
#if PBTCOMPILER
    internal class ParserContext : IUriContext
#else 
    public class ParserContext : IUriContext
#endif 
    { 

#region Public Methods 

        ///    
        ///    Constructor
        ///     
        public ParserContext()
        { 
            Initialize(); 
        }
 
        // Initialize the ParserContext to a known, default state.  DO NOT wipe out
        // data that may be able to be shared between seperate parses, such as the
        // xamlTypeMapper and the map table.
        internal void Initialize() 
        {
            _xmlnsDictionary = null;    // created on its first use 
#if !PBTCOMPILER 
            _nameScopeStack    = null;
#endif 
            _xmlLang        = String.Empty;
            _xmlSpace       = String.Empty;
        }
 

#if !PBTCOMPILER 
        ///  
        ///    Constructor that takes the XmlParserContext.
        ///    A parserContext object will be built based on this. 
        /// 
        /// xmlParserContext to use

        public ParserContext(XmlParserContext xmlParserContext) 
        {
            if (xmlParserContext == null) 
            { 
                throw new ArgumentNullException( "xmlParserContext" );
            } 

            _xmlLang     = xmlParserContext.XmlLang;

            TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof(XmlSpace)); 
            if (typeConverter != null)
                _xmlSpace = (string) typeConverter.ConvertToString(null, TCH.EnglishUSCulture, xmlParserContext.XmlSpace); 
            else 
                _xmlSpace = String.Empty;
 
            _xmlnsDictionary = new XmlnsDictionary() ;

            if (xmlParserContext.BaseURI != null && xmlParserContext.BaseURI.Length > 0)
            { 
                _baseUri = new Uri(xmlParserContext.BaseURI, UriKind.RelativeOrAbsolute);
            } 
 
            XmlNamespaceManager xmlnsManager = xmlParserContext.NamespaceManager;
 
            if (null != xmlnsManager)
            {
                foreach (string key in xmlnsManager)
                { 
                    _xmlnsDictionary.Add(key, xmlnsManager.LookupNamespace(key));
                } 
            } 
        }
#endif 

#if !PBTCOMPILER
        /// 
        /// Constructor overload that takes an XmlReader, in order to 
        /// pull the BaseURI, Lang, and Space from it.
        ///  
        internal ParserContext( XmlReader xmlReader ) 
        {
            if( xmlReader.BaseURI != null && xmlReader.BaseURI.Length != 0 ) 
            {
                BaseUri = new Uri( xmlReader.BaseURI );
            }
 
            XmlLang = xmlReader.XmlLang;
 
            if( xmlReader.XmlSpace != System.Xml.XmlSpace.None ) 
            {
                XmlSpace = xmlReader.XmlSpace.ToString(); 
            }
        }
#endif
 
#if !PBTCOMPILER
        ///  
        ///    Constructor that takes the ParserContext. 
        ///    A parserContext object will be built based on this.
        ///  
        /// xmlParserContext to use
        internal ParserContext(ParserContext parserContext)
        {
            _xmlLang     = parserContext.XmlLang; 
            _xmlSpace    = parserContext.XmlSpace;
            _xamlTypeMapper      = parserContext.XamlTypeMapper; 
            _mapTable    = parserContext.MapTable; 
            _baseUri     = parserContext.BaseUri;
 
            _rootElement = parserContext._rootElement;
            if (parserContext._nameScopeStack != null)
                _nameScopeStack = (Stack)parserContext._nameScopeStack.Clone();
            else 
                _nameScopeStack = null;
 
            // Don't want to force the lazy init so we just set privates 
            _skipJournaledProperties = parserContext._skipJournaledProperties;
 
            _xmlnsDictionary = null;

            // when there are no namespace prefix mappings in incoming ParserContext,
             // we are not going to create an empty XmlnsDictionary. 
            if (parserContext._xmlnsDictionary != null &&
                parserContext._xmlnsDictionary.Count > 0) 
            { 
                _xmlnsDictionary = new XmlnsDictionary();
 
                XmlnsDictionary xmlDictionaryFrom = parserContext.XmlnsDictionary;

                if (null != xmlDictionaryFrom)
                { 
                    foreach (string key in xmlDictionaryFrom.Keys)
                    { 
                        _xmlnsDictionary[key] = xmlDictionaryFrom[key]; 
                    }
                } 
            }
        }
#endif
 
        /// 
        /// Pushes the context scope stack (modifications to the ParserContext only apply to levels below 
        /// the modification in the stack, except for the XamlTypeMapper property) 
        /// 
        internal void PushScope() 
        {
            _repeat++;
            _currentFreezeStackFrame.IncrementRepeatCount();
 
            // Wait till the context needs XmlnsDictionary, create on first use.
            if (_xmlnsDictionary != null) 
                _xmlnsDictionary.PushScope(); 
        }
 
        /// 
        /// Pops the context scope stack
        /// 
        internal void PopScope() 
        {
            // Pop state off of the _langSpaceStack 
            if (_repeat > 0) 
            {
                _repeat--; 
            }
            else
            {
                if (null != _langSpaceStack && _langSpaceStack.Count > 0) 
                {
                    _repeat = (int) _langSpaceStack.Pop(); 
                    _targetType = (Type) _langSpaceStack.Pop(); 
                    _xmlSpace = (string) _langSpaceStack.Pop();
                    _xmlLang = (string) _langSpaceStack.Pop(); 
                }
            }

            // Pop state off of _currentFreezeStackFrame 
            if (!_currentFreezeStackFrame.DecrementRepeatCount())
            { 
                // If the end of the current frame has been reached, pop 
                // the next frame off the freeze stack
                _currentFreezeStackFrame = (FreezeStackFrame) _freezeStack.Pop(); 
            }

            // Wait till the context needs XmlnsDictionary, create on first use.
            if (_xmlnsDictionary != null) 
                _xmlnsDictionary.PopScope();
 
        } 

        ///  
        /// XmlNamespaceDictionary
        /// 
        public XmlnsDictionary  XmlnsDictionary
        { 
            get
            { 
                // Entry Point to others, initialize if null. 
                if (_xmlnsDictionary == null)
                    _xmlnsDictionary = new XmlnsDictionary(); 

                return _xmlnsDictionary;
            }
        } 

        ///  
        /// XmlLang property 
        /// 
        public string XmlLang 
        {
            get
            {
                return _xmlLang; 
            }
            set 
            { 
                EndRepeat();
                _xmlLang = (null == value ? String.Empty : value); 
            }
        }

        ///  
        /// XmlSpace property
        ///  
        // (Why isn't this of type XmlSpace?) 
        public string XmlSpace
        { 
            get
            {
                return _xmlSpace;
            } 
            set
            { 
                EndRepeat(); 
                _xmlSpace = value;
            } 
        }

        //
        // TargetType 
        //
        // Keep track of the Style/Template TargetType's in the current context.  This allows Setters etc 
        // to interpret properties without walking up the reader stack to see it.  This is internal and 
        // hard-coded to target type, but the intent in the future is to generalize this so that we don't
        // have to have the custom parser, and so that the designer can provide the same contextual information. 
        //
        internal Type TargetType
        {
            get 
            {
                return _targetType; 
            } 

#if !PBTCOMPILER 
            set
            {
                EndRepeat();
                _targetType = value; 
            }
#endif 
        } 

        // Items specific to XAML 

        /// 
        ///  XamlTypeMapper that should be used when resolving XML
        ///  
        public XamlTypeMapper XamlTypeMapper
        { 
            get 
            {
                return _xamlTypeMapper ; 
            }
            set
            {
                // The BamlMapTable must always be kept in [....] with the XamlTypeMapper.  If 
                // the XamlTypeMapper changes, then the map table must also be reset.
                if (_xamlTypeMapper != value) 
                { 
                    _xamlTypeMapper = value;
                    _mapTable = new BamlMapTable(value); 
                    _xamlTypeMapper.MapTable = _mapTable;
                }
            }
        } 
#if !PBTCOMPILER
        ///  
        ///  Gets or sets the list of INameScopes in parent chain 
        /// 
        internal Stack NameScopeStack 
        {
            get
            {
               if (_nameScopeStack == null) 
                   _nameScopeStack = new Stack(2);
 
               return _nameScopeStack; 
            }
        } 
#endif

        /// 
        ///    Gets or sets the base Uri 
        /// 
        public Uri BaseUri 
        { 
            get
            { 
                return _baseUri ;
            }
            set
            { 
                _baseUri = value;
            } 
        } 

#if !PBTCOMPILER 
        /// 
        /// Should DependencyProperties marked with the Journal metadata flag be set or skipped?
        /// 
        ///  
        internal bool SkipJournaledProperties
        { 
            get { return _skipJournaledProperties; } 
            set { _skipJournaledProperties = value; }
        } 

        //
        // The Assembly which hosts the Baml stream.
        // 
        /// 
        ///     Critical - because it sets the value of the _streamCreatedAssembly field, and that is 
        ///                SecurityCritical Data as this field is used by the BamlRecordReader to 
        ///                allow legitimate internal types in Partial Trust.
        ///  
        internal Assembly StreamCreatedAssembly
        {
            get { return _streamCreatedAssembly.Value; }
 
            [SecurityCritical]
            set { _streamCreatedAssembly.Value = value; } 
        } 
#endif
 
        /// 
        ///    Operator for Converting a ParserContext to an XmlParserContext
        /// 
        /// ParserContext to Convert 
        /// XmlParserContext
        public static implicit operator XmlParserContext(ParserContext parserContext) 
        { 
            return ParserContext.ToXmlParserContext(parserContext);
        } 


        /// 
        ///    Operator for Converting a ParserContext to an XmlParserContext 
        /// 
        /// ParserContext to Convert 
        /// XmlParserContext 
        public static XmlParserContext ToXmlParserContext(ParserContext parserContext)
        { 
            if (parserContext == null)
            {
                throw new ArgumentNullException( "parserContext" );
            } 

            XmlNamespaceManager xmlnsMgr = new XmlNamespaceManager(new NameTable()); 
            XmlSpace xmlSpace = System.Xml.XmlSpace.None; 

            if (parserContext.XmlSpace != null && parserContext.XmlSpace.Length != 0) 
            {
                TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof(System.Xml.XmlSpace));
                if (null != typeConverter)
                { 
                    try
                    { 
                        xmlSpace = (System.Xml.XmlSpace)typeConverter.ConvertFromString(null, TCH.EnglishUSCulture, parserContext.XmlSpace); 
                    }
                    catch (System.FormatException)  // If it's not a valid space value, ignore it 
                    {
                        xmlSpace = System.Xml.XmlSpace.None;
                    }
                } 
            }
 
            // We start getting Keys list only if we have non-empty dictionary 

            if (parserContext._xmlnsDictionary != null) 
            {
                foreach (string key in parserContext._xmlnsDictionary.Keys)
                {
                    xmlnsMgr.AddNamespace(key, parserContext._xmlnsDictionary[key]); 
                }
            } 
 
            XmlParserContext xmlParserContext = new XmlParserContext(null, xmlnsMgr, parserContext.XmlLang, xmlSpace);
            if( parserContext.BaseUri == null) 
            {
                xmlParserContext.BaseURI = null;
            }
            else 
            {
                string serializedSafe = parserContext.BaseUri.GetComponents(UriComponents.SerializationInfoString, UriFormat.SafeUnescaped); 
                Uri sameUri = new Uri(serializedSafe); 
                string cannonicalString =  sameUri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped);
                xmlParserContext.BaseURI = cannonicalString; 
            }

            return xmlParserContext;
        } 

#endregion Public Methods 
 
#region Internal
 

        // Reset stack to default state
        private void EndRepeat()
        { 
            if (_repeat > 0)
            { 
                if (null == _langSpaceStack) 
                {
                    _langSpaceStack = new Stack(1); 
                }

                _langSpaceStack.Push(XmlLang);
                _langSpaceStack.Push(XmlSpace); 
                _langSpaceStack.Push(TargetType);
                _langSpaceStack.Push(_repeat); 
                _repeat = 0; 
            }
        } 

        /// 
        /// LineNumber for the first character in the given
        /// stream. This is used when parsing a section of a larger file so 
        /// that proper line number in the overall file can be calculated.
        ///  
        internal int LineNumber 
        {
            get { return _lineNumber; } 
#if !PBTCOMPILER
            set { _lineNumber = value; }
#endif
        } 

 
        ///  
        /// LinePosition for the first character in the given
        /// stream. This is used when parsing a section of a larger file so 
        /// that proper line positions in the overall file can be calculated.
        /// 
        internal int LinePosition
        { 
            get { return _linePosition; }
#if !PBTCOMPILER 
            set { _linePosition = value; } 
#endif
        } 

#if !PBTCOMPILER
        internal bool IsDebugBamlStream
        { 
            get { return _isDebugBamlStream; }
            set { _isDebugBamlStream = value; } 
        } 

        ///  
        /// Gets or sets the object at the root of the portion of the tree
        /// currently being parsed.  Note that this may not be the very top of the tree
        /// if the parsing operation is scoped to a specific subtree, such as in Style
        /// parsing. 
        /// 
        internal object RootElement 
        { 
            get { return _rootElement; }
            set { _rootElement = value; } 
        }

        // If this is false (default), then the parser does not own the stream and so if
        // it has any defer loaded content, it needs to copy it into a byte array since 
        // the owner\caller will close the stream when parsing is complete. Currently, this
        // is set to true only by the theme engine since the stream is a system-wide resource 
        // an dso will always be open for teh lifetime of the process laoding the theme and so 
        // it can be re-used for perf reasons.
        internal bool OwnsBamlStream 
        {
            get { return _ownsBamlStream; }
            set { _ownsBamlStream = value; }
        } 
#endif
 
        ///  
        /// Allows sharing a map table between instances of BamlReaders and Writers.
        ///  

        internal BamlMapTable MapTable
        {
            get { return _mapTable; } 
#if !PBTCOMPILER
            set 
            { 
                // The XamlTypeMapper and the map table must always be kept in [....].  If the
                // map table changes, update the XamlTypeMapper also 
                if (_mapTable != value)
                {
                    _mapTable = value;
                    _xamlTypeMapper = _mapTable.XamlTypeMapper; 
                    _xamlTypeMapper.MapTable = _mapTable;
                } 
            } 
#endif
        } 

#if !PBTCOMPILER

        ///  
        ///  Allows accessing the associated BamlRecordReader for doing custom processing
        ///  and searches of the reader stack during parse time. 
        ///  
        internal BamlRecordReader BamlReader
        { 
            get { return _bamlRecordReader; }
            set { _bamlRecordReader = value; }
        }
 

        internal IStyleConnector StyleConnector 
        { 
            get { return _styleConnector; }
            set { _styleConnector = value; } 
        }

        // Keep a cached ProvideValueProvider so that we don't have to keep re-creating one.
        internal ProvideValueServiceProvider ProvideValueProvider 
        {
            get 
            { 
                if (_provideValueServiceProvider == null)
                { 
                    _provideValueServiceProvider = new ProvideValueServiceProvider(this);
                }

                return _provideValueServiceProvider; 
            }
        } 
 
        /// 
        /// This is used to resolve a StaticResourceId record within a deferred content 
        /// section against a StaticResourceExtension on the parent dictionary.
        /// 
        internal List StaticResourcesStack
        { 
            get
            { 
                if (_staticResourcesStack == null) 
                {
                    _staticResourcesStack = new List(); 
                }

                return _staticResourcesStack;
            } 
        }
 
        ///  
        /// Says if we are we currently loading deferred content
        ///  
        internal bool InDeferredSection
        {
            get { return (_staticResourcesStack != null && _staticResourcesStack.Count > 0); }
        } 
#endif
 
        // Return a new Parser context that has the same instance variables as this instance, with 
        // only scope dependent variables deep copied.  Variables that are not dependent on scope
        // (such as the baml map table) are not deep copied. 

#if !PBTCOMPILER
        internal ParserContext ScopedCopy()
        { 
            return ScopedCopy( true /* copyNameScopeStack */ );
        } 
#endif 

#if !PBTCOMPILER 
        /// 
        ///     Critical - because it sets _streamCreatedAssembly on the ParserContext, and that is
        ///                SecurityCritical Data as this field is used by the BamlRecordReader to
        ///                allow legitimate internal types in Partial Trust. 
        ///     Safe - because it gets this value from a copy of itself that gets it from a stream that
        ///            implements an internal IStreamInfo interface and IStreamInfo.Assembly is set\ 
        ///            by the ResourceContainer code that is SecurityCritical, but treated as safe. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal ParserContext ScopedCopy(bool copyNameScopeStack)
        {
            ParserContext context = new ParserContext();
 
            context._baseUri = _baseUri;
            context._skipJournaledProperties = _skipJournaledProperties; 
            context._xmlLang = _xmlLang; 
            context._xmlSpace = _xmlSpace;
            context._repeat = _repeat; 
            context._lineNumber = _lineNumber;
            context._linePosition = _linePosition;
            context._isDebugBamlStream = _isDebugBamlStream;
            context._mapTable = _mapTable; 
            context._xamlTypeMapper = _xamlTypeMapper;
            context._targetType = _targetType; 
 
            context._streamCreatedAssembly.Value = _streamCreatedAssembly.Value;
            context._rootElement = _rootElement; 
            context._styleConnector = _styleConnector;

            // Copy the name scope stack, if necessary.
 
            if (_nameScopeStack != null && copyNameScopeStack)
                context._nameScopeStack = (_nameScopeStack != null) ? (Stack)_nameScopeStack.Clone() : null; 
            else 
                context._nameScopeStack = null;
 
            // Deep copy only selected scope dependent instance variables
            context._langSpaceStack = (_langSpaceStack != null) ? (Stack)_langSpaceStack.Clone() : null;

            if (_xmlnsDictionary != null) 
                context._xmlnsDictionary = new XmlnsDictionary(_xmlnsDictionary);
            else 
                context._xmlnsDictionary = null; 

            context._currentFreezeStackFrame = _currentFreezeStackFrame; 
            context._freezeStack = (_freezeStack != null) ? (Stack) _freezeStack.Clone() : null;

            return context;
        } 
#endif
 
        // 
        // This is called by a user of a parser context when it is a good time to drop unnecessary
        // references (today, just an empty stack). 
        //

#if !PBTCOMPILER
        internal void TrimState() 
        {
 
                if( _nameScopeStack != null && _nameScopeStack.Count == 0 ) 
                {
                    _nameScopeStack = null; 
                }

        }
#endif 

        // Return a new Parser context that has the same instance variables as this instance, 
        // will all scoped and non-scoped complex properties deep copied. 
#if !PBTCOMPILER
        internal ParserContext Clone() 
        {
            ParserContext context = ScopedCopy();

            // Deep copy only selected instance variables 
            context._mapTable = (_mapTable != null) ? _mapTable.Clone() : null;
            context._xamlTypeMapper = (_xamlTypeMapper != null) ? _xamlTypeMapper.Clone() : null; 
 
            // Connect the XamlTypeMapper and bamlmaptable
            context._xamlTypeMapper.MapTable = context._mapTable; 
            context._mapTable.XamlTypeMapper = context._xamlTypeMapper;

            return context;
        } 
#endif
 
#if !PBTCOMPILER 
        // Set/Get whether or not Freezables within the current scope
        // should be Frozen. 
        internal bool FreezeFreezables
        {
            get
            { 
                return _currentFreezeStackFrame.FreezeFreezables;
            } 
 
            set
            { 
                // If the freeze flag isn't actually changing, we don't need to
                // register a change
                if (value != _currentFreezeStackFrame.FreezeFreezables)
                { 
                    // When this scope was entered the repeat count was initially incremented,
                    // indicating no _freezeFreezables state changes within this scope. 
                    // 
                    // Now that a state change has been found, we need to replace that no-op with
                    // a directive to restore the old state by un-doing the increment 
                    // and pushing the stack frame
#if DEBUG
                    bool canDecrement =
#endif 
                    _currentFreezeStackFrame.DecrementRepeatCount();
#if DEBUG 
                    // We're replacing a no-op with a state change.  Detect if we accidently 
                    // start replacing actual state changes.  This might happen if we allowed
                    // FreezeFreezable to be set twice within the same scope, for 
                    // example.
                    Debug.Assert(canDecrement);
#endif
                    if (_freezeStack == null) 
                    {
                        // Lazily allocate a _freezeStack if this is the first 
                        // state change. 
                        _freezeStack = new Stack();
                    } 

                    // Save the old frame
                    _freezeStack.Push(_currentFreezeStackFrame);
 
                    // Set the new frame
                    _currentFreezeStackFrame.Reset(value); 
                } 
            }
        } 

        internal bool TryCacheFreezable(string value, Freezable freezable)
        {
            if (FreezeFreezables) 
            {
                if (freezable.CanFreeze) 
                { 
                    if (!freezable.IsFrozen)
                    { 
                        freezable.Freeze();
                    }
                    if (_freezeCache == null)
                    { 
                        _freezeCache = new Dictionary();
                    } 
                    _freezeCache.Add(value, freezable); 
                    return true;
                } 
            }

            return false;
        } 

        internal Freezable TryGetFreezable(string value) 
        { 
            Freezable freezable = null;
            if (_freezeCache != null) 
            {
                _freezeCache.TryGetValue(value, out freezable);
            }
 
            return freezable;
        } 
#endif 

#endregion Internal 

#region Date

        private XamlTypeMapper          _xamlTypeMapper; 
        private Uri                     _baseUri;
 
        private XmlnsDictionary         _xmlnsDictionary; 
        private String                  _xmlLang        = String.Empty;
        private String                  _xmlSpace       = String.Empty; 
        private Stack                   _langSpaceStack;
        private int                     _repeat;
        private Type                    _targetType;
 
#if !PBTCOMPILER
        private bool                    _skipJournaledProperties; 
        private SecurityCriticalDataForSet _streamCreatedAssembly; 
        private bool                    _ownsBamlStream;
        private ProvideValueServiceProvider _provideValueServiceProvider; 
        private IStyleConnector _styleConnector;
        private Stack                   _nameScopeStack;
        private BamlRecordReader        _bamlRecordReader;
        private List          _staticResourcesStack; 

        object                                      _rootElement;  // RootElement for the Page scoping [temporary, should be 
        // something like page name or baseUri] 

#endif 

        // Struct that maintains both the freezeFreezable state & stack depth
        // between freezeFreezable state changes
        private struct FreezeStackFrame 
        {
            internal void IncrementRepeatCount() { _repeatCount++; } 
 
            // Returns false when the count reaches 0 such that the decrement can not occur
            internal bool DecrementRepeatCount() 
            {
                if (_repeatCount > 0)
                {
                    _repeatCount--; 
                    return true;
                } 
                else 
                {
                    return false; 
                }
            }

#if !PBTCOMPILER 
            // Accessors for private state
            internal bool FreezeFreezables 
            { 
                get { return _freezeFreezables; }
            } 

            // Reset's this frame to a new scope.  Only used with _currentFreezeStackFrame.
            internal void Reset(bool freezeFreezables)
            { 
                _freezeFreezables = freezeFreezables;
                _repeatCount = 0; 
            } 

            // Whether or not Freezeables with the current scope should be Frozen 
            private bool _freezeFreezables;

#endif
 
            // The number of frames until the next state change.
            // We need to know how many times PopScope() is called until the 
            // state changes.  That information is tracked by _repeatCount. 
            private int _repeatCount;
        } 

        // First frame is maintained off of the _freezeStack to avoid allocating
        // a Stack for the common case where Freeze isn't specified.
        FreezeStackFrame _currentFreezeStackFrame; 

#if !PBTCOMPILER 
        // When cloning, it isn't necessary to copy this cache of freezables. 
        // This cache allows frozen freezables to use a shared instance and save on memory.
        private Dictionary _freezeCache; 
#endif

        private Stack _freezeStack = null;
 
        private int _lineNumber = 0;    // number of lines between the start of the file and
                                        // our starting point (the starting point of this context) 
        private int _linePosition=0;      // default start ot left of first character which is a zero 
        private BamlMapTable _mapTable;
#if !PBTCOMPILER 
        private bool _isDebugBamlStream = false;
#endif
#endregion Data
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK