The Labs \ Source Viewer \ SSCLI \ System.Xml \ DomNameTable

  1. //------------------------------------------------------------------------------
  2. // <copyright file="DomNameTable.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. using System;
  16. using System.Diagnostics;
  17. using System.Xml.Schema;
  18. namespace System.Xml
  19. {
  20.    
  21.     internal class DomNameTable
  22.     {
  23.         XmlName[] entries;
  24.         int count;
  25.         int mask;
  26.         XmlDocument ownerDocument;
  27.         XmlNameTable nameTable;
  28.        
  29.         const int InitialSize = 64;
  30.         // must be a power of two
  31.         public DomNameTable(XmlDocument document)
  32.         {
  33.             ownerDocument = document;
  34.             nameTable = document.NameTable;
  35.             entries = new XmlName[InitialSize];
  36.             mask = InitialSize - 1;
  37.             Debug.Assert((entries.Length & mask) == 0);
  38.             // entries.Length must be a power of two
  39.         }
  40.        
  41.         public XmlName GetName(string prefix, string localName, string ns, IXmlSchemaInfo schemaInfo)
  42.         {
  43.             if (prefix == null) {
  44.                 prefix = string.Empty;
  45.             }
  46.             if (ns == null) {
  47.                 ns = string.Empty;
  48.             }
  49.            
  50.             int hashCode = XmlName.GetHashCode(localName);
  51.            
  52.             for (XmlName e = entries[hashCode & mask]; e != null; e = e.next) {
  53.                 if (e.HashCode == hashCode && ((object)e.LocalName == (object)localName || e.LocalName.Equals(localName)) && ((object)e.Prefix == (object)prefix || e.Prefix.Equals(prefix)) && ((object)e.NamespaceURI == (object)ns || e.NamespaceURI.Equals(ns)) && e.Equals(schemaInfo)) {
  54.                     return e;
  55.                 }
  56.             }
  57.             return null;
  58.         }
  59.        
  60.         public XmlName AddName(string prefix, string localName, string ns, IXmlSchemaInfo schemaInfo)
  61.         {
  62.             if (prefix == null) {
  63.                 prefix = string.Empty;
  64.             }
  65.             if (ns == null) {
  66.                 ns = string.Empty;
  67.             }
  68.            
  69.             int hashCode = XmlName.GetHashCode(localName);
  70.            
  71.             for (XmlName e = entries[hashCode & mask]; e != null; e = e.next) {
  72.                 if (e.HashCode == hashCode && ((object)e.LocalName == (object)localName || e.LocalName.Equals(localName)) && ((object)e.Prefix == (object)prefix || e.Prefix.Equals(prefix)) && ((object)e.NamespaceURI == (object)ns || e.NamespaceURI.Equals(ns)) && e.Equals(schemaInfo)) {
  73.                     return e;
  74.                 }
  75.             }
  76.            
  77.             prefix = nameTable.Add(prefix);
  78.             localName = nameTable.Add(localName);
  79.             ns = nameTable.Add(ns);
  80.             int index = hashCode & mask;
  81.             XmlName name = XmlName.Create(prefix, localName, ns, hashCode, ownerDocument, entries[index], schemaInfo);
  82.             entries[index] = name;
  83.            
  84.             if (count++ == mask) {
  85.                 Grow();
  86.             }
  87.            
  88.             return name;
  89.         }
  90.        
  91.         private void Grow()
  92.         {
  93.             int newMask = mask * 2 + 1;
  94.             XmlName[] oldEntries = entries;
  95.             XmlName[] newEntries = new XmlName[newMask + 1];
  96.            
  97.             // use oldEntries.Length to eliminate the rangecheck
  98.             for (int i = 0; i < oldEntries.Length; i++) {
  99.                 XmlName name = oldEntries[i];
  100.                 while (name != null) {
  101.                     int newIndex = name.HashCode & newMask;
  102.                     XmlName tmp = name.next;
  103.                     name.next = newEntries[newIndex];
  104.                     newEntries[newIndex] = name;
  105.                     name = tmp;
  106.                 }
  107.             }
  108.             entries = newEntries;
  109.             mask = newMask;
  110.         }
  111.     }
  112. }

Developer Fusion