1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
|
//------------------------------------------------------------------------------
// <copyright file="XmlQualifiedName.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">Microsoft</owner>
//------------------------------------------------------------------------------
namespace System.Xml {
using System.Collections;
using System.Diagnostics;
#if !SILVERLIGHT
using Microsoft.Win32;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
#endif
/// <include file='doc\XmlQualifiedName.uex' path='docs/doc[@for="XmlQualifiedName"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
#if !SILVERLIGHT
[Serializable]
#endif
public class XmlQualifiedName {
#if !SILVERLIGHT
delegate int HashCodeOfStringDelegate(string s, int sLen, long additionalEntropy);
static HashCodeOfStringDelegate hashCodeDelegate = null;
#endif
string name;
string ns;
#if !SILVERLIGHT
[NonSerialized]
#endif
Int32 hash;
/// <include file='doc\XmlQualifiedName.uex' path='docs/doc[@for="XmlQualifiedName.Empty"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public static readonly XmlQualifiedName Empty = new XmlQualifiedName(string.Empty);
/// <include file='doc\XmlQualifiedName.uex' path='docs/doc[@for="XmlQualifiedName.XmlQualifiedName"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public XmlQualifiedName() : this(string.Empty, string.Empty) {}
/// <include file='doc\XmlQualifiedName.uex' path='docs/doc[@for="XmlQualifiedName.XmlQualifiedName1"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public XmlQualifiedName(string name) : this(name, string.Empty) {}
/// <include file='doc\XmlQualifiedName.uex' path='docs/doc[@for="XmlQualifiedName.XmlQualifiedName2"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public XmlQualifiedName(string name, string ns) {
this.ns = ns == null ? string.Empty : ns;
this.name = name == null ? string.Empty : name;
}
/// <include file='doc\XmlQualifiedName.uex' path='docs/doc[@for="XmlQualifiedName.Namespace"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public string Namespace {
get { return ns; }
}
/// <include file='doc\XmlQualifiedName.uex' path='docs/doc[@for="XmlQualifiedName.Name"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public string Name {
get { return name; }
}
/// <include file='doc\XmlQualifiedName.uex' path='docs/doc[@for="XmlQualifiedName.GetHashCode"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public override int GetHashCode() {
if(hash == 0) {
#if !SILVERLIGHT
if (hashCodeDelegate == null) {
hashCodeDelegate = GetHashCodeDelegate();
}
hash = hashCodeDelegate(Name, Name.Length, 0);
#else
hash = Name.GetHashCode() /*+ Namespace.GetHashCode()*/; // for perf reasons we are not taking ns's hashcode.
#endif
}
return hash;
}
/// <include file='doc\XmlQualifiedName.uex' path='docs/doc[@for="XmlQualifiedName.IsEmpty"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public bool IsEmpty {
get { return Name.Length == 0 && Namespace.Length == 0; }
}
/// <include file='doc\XmlQualifiedName.uex' path='docs/doc[@for="XmlQualifiedName.ToString"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public override string ToString() {
return Namespace.Length == 0 ? Name : string.Concat(Namespace, ":" , Name);
}
/// <include file='doc\XmlQualifiedName.uex' path='docs/doc[@for="XmlQualifiedName.Equals"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public override bool Equals(object other) {
XmlQualifiedName qname;
if ((object) this == other) {
return true;
}
qname = other as XmlQualifiedName;
if (qname != null) {
return (Name == qname.Name && Namespace == qname.Namespace);
}
return false;
}
/// <include file='doc\XmlQualifiedName.uex' path='docs/doc[@for="XmlQualifiedName.operator=="]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public static bool operator ==(XmlQualifiedName a, XmlQualifiedName b) {
if ((object) a == (object) b)
return true;
if ((object) a == null || (object) b == null)
return false;
return (a.Name == b.Name && a.Namespace == b.Namespace);
}
/// <include file='doc\XmlQualifiedName.uex' path='docs/doc[@for="XmlQualifiedName.operator!="]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public static bool operator !=(XmlQualifiedName a, XmlQualifiedName b) {
return !(a == b);
}
/// <include file='doc\XmlQualifiedName.uex' path='docs/doc[@for="XmlQualifiedName.ToString1"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public static string ToString(string name, string ns) {
return ns == null || ns.Length == 0 ? name : ns + ":" + name;
}
#if !SILVERLIGHT // These methods are not used in Silverlight
[SecuritySafeCritical]
#if !MOBILE
[ReflectionPermission(SecurityAction.Assert, Unrestricted = true)]
#endif
private static HashCodeOfStringDelegate GetHashCodeDelegate() {
// If we are using randomized hashing and we find the Marving hash method, we use that
// Otherwise, we use the old string hashing function.
if (!IsRandomizedHashingDisabled())
{
MethodInfo getHashCodeMethodInfo = typeof(String).GetMethod("InternalMarvin32HashString", BindingFlags.NonPublic | BindingFlags.Static);
if (getHashCodeMethodInfo != null)
{
return (HashCodeOfStringDelegate)Delegate.CreateDelegate(typeof(HashCodeOfStringDelegate), getHashCodeMethodInfo);
}
// This will fall through and return a delegate to the old hash function
Debug.Assert(false, "Randomized hashing is not supported.");
}
return new HashCodeOfStringDelegate(GetHashCodeOfString);
}
#if MONO
static bool IsRandomizedHashingDisabled ()
{
return false;
}
#else
[SecuritySafeCritical]
[RegistryPermission(SecurityAction.Assert, Unrestricted = true)]
private static bool IsRandomizedHashingDisabled() {
const string regValueName = "DisableRandomizedHashingOnXmlQualifiedName";
bool disableHashing = false; // default value
if (!ReadBoolFromXmlRegistrySettings(Registry.CurrentUser, regValueName, ref disableHashing)) {
ReadBoolFromXmlRegistrySettings(Registry.LocalMachine, regValueName, ref disableHashing);
}
return disableHashing;
}
[SecurityCritical]
private static bool ReadBoolFromXmlRegistrySettings(RegistryKey hive, string regValueName, ref bool value) {
const string regValuePath = @"SOFTWARE\Microsoft\.NETFramework\XML";
try {
using (RegistryKey xmlRegKey = hive.OpenSubKey(regValuePath, false)) {
if (xmlRegKey != null) {
if (xmlRegKey.GetValueKind(regValueName) == RegistryValueKind.DWord) {
value = ((int)xmlRegKey.GetValue(regValueName)) == 1;
return true;
}
}
}
}
catch { /* use the default if we couldn't read the key */ }
return false;
}
#endif
private static int GetHashCodeOfString(string s, int length, long additionalEntropy)
{
// This is the fallback method for calling the regular hashcode method
return s.GetHashCode();
}
// --------- Some useful internal stuff -----------------
internal void Init(string name, string ns) {
Debug.Assert(name != null && ns != null);
this.name = name;
this.ns = ns;
this.hash = 0;
}
internal void SetNamespace(string ns) {
Debug.Assert(ns != null);
this.ns = ns; //Not changing hash since ns is not used to compute hashcode
}
internal void Verify() {
XmlConvert.VerifyNCName(name);
if (ns.Length != 0) {
XmlConvert.ToUri(ns);
}
}
internal void Atomize(XmlNameTable nameTable) {
Debug.Assert(name != null);
name = nameTable.Add(name);
ns = nameTable.Add(ns);
}
internal static XmlQualifiedName Parse(string s, IXmlNamespaceResolver nsmgr, out string prefix) {
string localName;
ValidateNames.ParseQNameThrow(s, out prefix, out localName);
string uri = nsmgr.LookupNamespace(prefix);
if (uri == null) {
if (prefix.Length != 0) {
throw new XmlException(Res.Xml_UnknownNs, prefix);
}
else { //Re-map namespace of empty prefix to string.Empty when there is no default namespace declared
uri = string.Empty;
}
}
return new XmlQualifiedName(localName, uri);
}
internal XmlQualifiedName Clone() {
return (XmlQualifiedName)MemberwiseClone();
}
internal static int Compare(XmlQualifiedName a, XmlQualifiedName b) {
if (null == a) {
return (null == b) ? 0 : -1;
}
if (null == b) {
return 1;
}
int i = String.CompareOrdinal(a.Namespace, b.Namespace);
if (i == 0) {
i = String.CompareOrdinal(a.Name, b.Name);
}
return i;
}
#endif
}
}
|