You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@ -0,0 +1,166 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="WhitespaceRuleLookup.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
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 {
|
||||
|
||||
/// <summary>
|
||||
/// This class keeps a list of whitespace rules in order to determine whether whitespace children of particular
|
||||
/// elements should be stripped.
|
||||
/// </summary>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new lookup internal class from the specified WhitespaceRules.
|
||||
/// </summary>
|
||||
public WhitespaceRuleLookup(IList<WhitespaceRule> 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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Atomize all names contained within the whitespace rules with respect to "nameTable".
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user