WhitespaceRuleLookup.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / XmlUtils / System / Xml / Xsl / Runtime / WhitespaceRuleLookup.cs / 1305376 / WhitespaceRuleLookup.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
using System; 
using System.Xml; 
using System.Collections;
using System.Collections.Generic; 
using System.Diagnostics;
using MS.Internal.Xml;
using System.Xml.Xsl.Qil;
 
namespace System.Xml.Xsl.Runtime {
 
    ///  
    /// This class keeps a list of whitespace rules in order to determine whether whitespace children of particular
    /// elements should be stripped. 
    /// 
    internal class WhitespaceRuleLookup {
        private Hashtable qnames;
        private ArrayList wildcards; 
        private InternalWhitespaceRule ruleTemp;
        private XmlNameTable nameTable; 
 
        public WhitespaceRuleLookup() {
            this.qnames = new Hashtable(); 
            this.wildcards = new ArrayList();
        }

        ///  
        /// Create a new lookup internal class from the specified WhitespaceRules.
        ///  
        public WhitespaceRuleLookup(IList rules) : this() { 
            WhitespaceRule rule;
            InternalWhitespaceRule ruleInternal; 
            Debug.Assert(rules != null);

            for (int i = rules.Count - 1; i >= 0; i--) {
                // Make a copy of each rule 
                rule = rules[i];
                ruleInternal = new InternalWhitespaceRule(rule.LocalName, rule.NamespaceName, rule.PreserveSpace, -i); 
 
                if (rule.LocalName == null || rule.NamespaceName == null) {
                    // Wildcard, so add to wildcards array 
                    this.wildcards.Add(ruleInternal);
                }
                else {
                    // Exact name, so add to hashtable 
                    this.qnames[ruleInternal] = ruleInternal;
                } 
            } 

            // Create a temporary (not thread-safe) InternalWhitespaceRule used for lookups 
            this.ruleTemp = new InternalWhitespaceRule();
        }

        ///  
        /// Atomize all names contained within the whitespace rules with respect to "nameTable".
        ///  
        public void Atomize(XmlNameTable nameTable) { 
            // If names are already atomized with respect to "nameTable", no need to do it again
            if (nameTable != this.nameTable) { 
                this.nameTable = nameTable;

                foreach (InternalWhitespaceRule rule in this.qnames.Values)
                    rule.Atomize(nameTable); 

                foreach (InternalWhitespaceRule rule in this.wildcards) 
                    rule.Atomize(nameTable); 
            }
        } 

        /// 
        /// Return true if elements of the specified name should have whitespace children stripped.
        /// NOTE: This method is not thread-safe.  Different threads should create their own copy of the 
        /// WhitespaceRuleLookup object.  This allows all names to be atomized according to a private NameTable.
        ///  
        public bool ShouldStripSpace(string localName, string namespaceName) { 
            InternalWhitespaceRule qnameRule, wildcardRule;
            Debug.Assert(this.nameTable != null && this.ruleTemp != null); 
            Debug.Assert(localName != null && (object) this.nameTable.Get(localName) == (object) localName);
            Debug.Assert(namespaceName != null && (object) this.nameTable.Get(namespaceName) == (object) namespaceName);

            this.ruleTemp.Init(localName, namespaceName, false, 0); 

            // Lookup name in qnames table 
            // If found, the name will be stripped unless there is a preserve wildcard with higher priority 
            qnameRule = this.qnames[this.ruleTemp] as InternalWhitespaceRule;
 
            for (int pos = this.wildcards.Count; pos-- != 0;) {
                wildcardRule = this.wildcards[pos] as InternalWhitespaceRule;

                if (qnameRule != null) { 
                    // If qname priority is greater than any subsequent wildcard's priority, then we're done
                    if (qnameRule.Priority > wildcardRule.Priority) 
                        return !qnameRule.PreserveSpace; 

                    // Don't bother to consider wildcards with the same PreserveSpace flag 
                    if (qnameRule.PreserveSpace == wildcardRule.PreserveSpace)
                        continue;
                }
 
                if (wildcardRule.LocalName == null || (object) wildcardRule.LocalName == (object) localName) {
                    if (wildcardRule.NamespaceName == null || (object) wildcardRule.NamespaceName == (object) namespaceName) { 
                        // Found wildcard match, so we're done (since wildcards are in priority order) 
                        return !wildcardRule.PreserveSpace;
                    } 
                }
            }

            return (qnameRule != null && !qnameRule.PreserveSpace); 
        }
 
        private class InternalWhitespaceRule : WhitespaceRule { 
            private int priority;       // Relative priority of this test
            private int hashCode;       // Cached hashcode 

            public InternalWhitespaceRule() {
            }
 
            public InternalWhitespaceRule(string localName, string namespaceName, bool preserveSpace, int priority) {
                Init(localName, namespaceName, preserveSpace, priority); 
            } 

            public void Init(string localName, string namespaceName, bool preserveSpace, int priority) { 
                base.Init(localName, namespaceName, preserveSpace);
                this.priority = priority;

                if (localName != null && namespaceName != null) { 
                    this.hashCode = localName.GetHashCode();
                } 
            } 

            public void Atomize(XmlNameTable nameTable) { 
                if (LocalName != null)
                    LocalName = nameTable.Add(LocalName);

                if (NamespaceName != null) 
                    NamespaceName = nameTable.Add(NamespaceName);
            } 
 
            public int Priority {
                get { return this.priority; } 
            }

            public override int GetHashCode() {
                return this.hashCode; 
            }
 
            public override bool Equals(object obj) { 
                Debug.Assert(obj is InternalWhitespaceRule);
                InternalWhitespaceRule that = obj as InternalWhitespaceRule; 

                Debug.Assert(LocalName != null && that.LocalName != null);
                Debug.Assert(NamespaceName != null && that.NamespaceName != null);
 
                // string == operator compares object references first and if they are not the same compares contents
                // of the compared strings. As a result we do not have to cast strings to objects to force reference 
                // comparison for atomized LocalNames and NamespaceNames. 
                return LocalName == that.LocalName && NamespaceName == that.NamespaceName;
            } 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

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