internal static XNamespace Get(string namespaceName, int index, int count) { XNamespace namespace2; if (count == 0) { return(None); } if (namespaces == null) { Interlocked.CompareExchange <XHashtable <WeakReference> >(ref namespaces, new XHashtable <WeakReference>(new XHashtable <WeakReference> .ExtractKeyDelegate(XNamespace.ExtractNamespace), 0x20), null); } do { WeakReference reference; if (!namespaces.TryGetValue(namespaceName, index, count, out reference)) { if ((count == "http://www.w3.org/XML/1998/namespace".Length) && (string.CompareOrdinal(namespaceName, index, "http://www.w3.org/XML/1998/namespace", 0, count) == 0)) { return(Xml); } if ((count == "http://www.w3.org/2000/xmlns/".Length) && (string.CompareOrdinal(namespaceName, index, "http://www.w3.org/2000/xmlns/", 0, count) == 0)) { return(Xmlns); } reference = namespaces.Add(new WeakReference(new XNamespace(namespaceName.Substring(index, count)))); } namespace2 = (reference != null) ? ((XNamespace)reference.Target) : null; }while (namespace2 == null); return(namespace2); }
/// <summary> /// Returns an <see cref="XName"/> created from this XNamespace <see cref="XName"/> and a portion of the passed in /// local name parameter. The returned <see cref="XName"/> object is guaranteed to be atomic (i.e. the only one in the system for /// this particular expanded name). /// </summary> internal XName GetName(string localName, int index, int count) { Debug.Assert(index >= 0 && index <= localName.Length, "Caller should have checked that index was in bounds"); Debug.Assert(count >= 0 && index + count <= localName.Length, "Caller should have checked that count was in bounds"); // Attempt to get the local name from the hash table XName?name; if (_names.TryGetValue(localName, index, count, out name)) { return(name); } // No local name has yet been added, so add it now return(_names.Add(new XName(this, localName.Substring(index, count)))); }
/// <summary> /// Returns an <see cref="XNamespace"/> created from a portion of the passed in namespace name parameter. The returned <see cref="XNamespace"/> /// object is guaranteed to be atomic (i.e. the only one in the system for this particular namespace name). /// </summary> internal static XNamespace Get(string namespaceName, int index, int count) { Debug.Assert(index >= 0 && index <= namespaceName.Length, "Caller should have checked that index was in bounds"); Debug.Assert(count >= 0 && index + count <= namespaceName.Length, "Caller should have checked that count was in bounds"); if (count == 0) { return(None); } // Use CompareExchange to ensure that exactly one XHashtable<WeakReference> is used to store namespaces if (s_namespaces == null) { Interlocked.CompareExchange(ref s_namespaces, new XHashtable <WeakReference <XNamespace> >(ExtractNamespace, NamespacesCapacity), null); } WeakReference <XNamespace>?refNamespace; XNamespace?ns; // Keep looping until a non-null namespace has been retrieved do { // Attempt to get the WeakReference for the namespace from the hash table if (!s_namespaces.TryGetValue(namespaceName, index, count, out refNamespace)) { // If it is not there, first determine whether it's a special namespace if (count == xmlPrefixNamespace.Length && string.CompareOrdinal(namespaceName, index, xmlPrefixNamespace, 0, count) == 0) { return(Xml); } if (count == xmlnsPrefixNamespace.Length && string.CompareOrdinal(namespaceName, index, xmlnsPrefixNamespace, 0, count) == 0) { return(Xmlns); } // Go ahead and create the namespace and add it to the table refNamespace = s_namespaces.Add(new WeakReference <XNamespace>(new XNamespace(namespaceName.Substring(index, count)))); } ns = refNamespace != null && refNamespace.TryGetTarget(out XNamespace? target) ? target : null; }while (ns == null); return(ns); }