The Labs \ Source Viewer \ SSCLI \ System.Xml.Schema \ XSODictionaryEnumerator

  1. //------------------------------------------------------------------------------
  2. // <copyright file="XmlSchemaObjectTable.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. // <owner current="true" primary="true">priyal</owner>
  15. //------------------------------------------------------------------------------
  16. namespace System.Xml.Schema
  17. {
  18.    
  19.     using System.Collections;
  20.     using System.Collections.Generic;
  21.     using System.Diagnostics;
  22.    
  23.     /// <include file='doc\XmlSchemaObjectTable.uex' path='docs/doc[@for="XmlSchemaObjectTable"]/*' />
  24.     public class XmlSchemaObjectTable
  25.     {
  26.         Dictionary<XmlQualifiedName, XmlSchemaObject> table = new Dictionary<XmlQualifiedName, XmlSchemaObject>();
  27.         List<XmlSchemaObjectEntry> entries = new List<XmlSchemaObjectEntry>();
  28.        
  29.         internal XmlSchemaObjectTable()
  30.         {
  31.         }
  32.        
  33.         internal void Add(XmlQualifiedName name, XmlSchemaObject value)
  34.         {
  35.             Debug.Assert(!table.ContainsKey(name), "XmlSchemaObjectTable.Add: entry already exists");
  36.             table.Add(name, value);
  37.             entries.Add(new XmlSchemaObjectEntry(name, value));
  38.         }
  39.        
  40.         internal void Insert(XmlQualifiedName name, XmlSchemaObject value)
  41.         {
  42.             XmlSchemaObject oldValue = null;
  43.             if (table.TryGetValue(name, out oldValue)) {
  44.                 table[name] = value;
  45.                 //set new value
  46.                 Debug.Assert(oldValue != null);
  47.                 int matchedIndex = FindIndexByValue(oldValue);
  48.                 Debug.Assert(matchedIndex >= 0);
  49.                 //set new entry
  50.                 Debug.Assert(entries[matchedIndex].qname == name);
  51.                 entries[matchedIndex] = new XmlSchemaObjectEntry(name, value);
  52.             }
  53.             else {
  54.                 Add(name, value);
  55.             }
  56.            
  57.         }
  58.        
  59.         internal void Replace(XmlQualifiedName name, XmlSchemaObject value)
  60.         {
  61.             XmlSchemaObject oldValue;
  62.             if (table.TryGetValue(name, out oldValue)) {
  63.                 table[name] = value;
  64.                 //set new value
  65.                 Debug.Assert(oldValue != null);
  66.                 int matchedIndex = FindIndexByValue(oldValue);
  67.                 Debug.Assert(entries[matchedIndex].qname == name);
  68.                 entries[matchedIndex] = new XmlSchemaObjectEntry(name, value);
  69.             }
  70.         }
  71.        
  72.         internal void Clear()
  73.         {
  74.             table.Clear();
  75.             entries.Clear();
  76.         }
  77.        
  78.         internal void Remove(XmlQualifiedName name)
  79.         {
  80.             XmlSchemaObject value;
  81.             if (table.TryGetValue(name, out value)) {
  82.                 table.Remove(name);
  83.                 int matchedIndex = FindIndexByValue(value);
  84.                 Debug.Assert(matchedIndex >= 0);
  85.                 Debug.Assert(entries[matchedIndex].qname == name);
  86.                 entries.RemoveAt(matchedIndex);
  87.             }
  88.         }
  89.        
  90.         private int FindIndexByValue(XmlSchemaObject xso)
  91.         {
  92.             int index;
  93.             for (index = 0; index < entries.Count; index++) {
  94.                 if ((object)entries[index].xso == (object)xso) {
  95.                     return index;
  96.                 }
  97.             }
  98.             return -1;
  99.         }
  100.         /// <include file='doc\XmlSchemaObjectTable.uex' path='docs/doc[@for="XmlSchemaObjectTable.Count"]/*' />
  101.         public int Count {
  102.             get {
  103.                 Debug.Assert(table.Count == entries.Count);
  104.                 return table.Count;
  105.             }
  106.         }
  107.        
  108.         /// <include file='doc\XmlSchemaObjectTable.uex' path='docs/doc[@for="XmlSchemaObjectTable.Contains"]/*' />
  109.         public bool Contains(XmlQualifiedName name)
  110.         {
  111.             return table.ContainsKey(name);
  112.         }
  113.        
  114.         /// <include file='doc\XmlSchemaObjectTable.uex' path='docs/doc[@for="XmlSchemaObjectTable.this"]/*' />
  115.         public XmlSchemaObject this[XmlQualifiedName name]
  116.         {
  117.             get {
  118.                 XmlSchemaObject value;
  119.                 if (table.TryGetValue(name, out value)) {
  120.                     return value;
  121.                 }
  122.                 return null;
  123.             }
  124.         }
  125.        
  126.         /// <include file='doc\XmlSchemaObjectTable.uex' path='docs/doc[@for="XmlSchemaObjectTable.Names"]/*' />
  127.         public ICollection Names {
  128.             get { return new NamesCollection(entries, table.Count); }
  129.         }
  130.        
  131.         /// <include file='doc\XmlSchemaObjectTable.uex' path='docs/doc[@for="XmlSchemaObjectTable.Values"]/*' />
  132.         public ICollection Values {
  133.             get { return new ValuesCollection(entries, table.Count); }
  134.         }
  135.        
  136.         /// <include file='doc\XmlSchemaObjectTable.uex' path='docs/doc[@for="XmlSchemaObjectTable.GetEnumerator"]/*' />
  137.         public IDictionaryEnumerator GetEnumerator()
  138.         {
  139.             return new XSODictionaryEnumerator(this.entries, table.Count, EnumeratorType.DictionaryEntry);
  140.         }
  141.        
  142.         internal enum EnumeratorType
  143.         {
  144.             Keys,
  145.             Values,
  146.             DictionaryEntry
  147.         }
  148.        
  149.         internal struct XmlSchemaObjectEntry
  150.         {
  151.             internal XmlQualifiedName qname;
  152.             internal XmlSchemaObject xso;
  153.            
  154.             public XmlSchemaObjectEntry(XmlQualifiedName name, XmlSchemaObject value)
  155.             {
  156.                 qname = name;
  157.                 xso = value;
  158.             }
  159.            
  160.             public XmlSchemaObject IsMatch(string localName, string ns)
  161.             {
  162.                 if (localName == qname.Name && ns == qname.Namespace) {
  163.                     return xso;
  164.                 }
  165.                 return null;
  166.             }
  167.            
  168.             public void Reset()
  169.             {
  170.                 qname = null;
  171.                 xso = null;
  172.             }
  173.         }
  174.        
  175.         internal class NamesCollection : ICollection
  176.         {
  177.             private List<XmlSchemaObjectEntry> entries;
  178.             int size;
  179.            
  180.             internal NamesCollection(List<XmlSchemaObjectEntry> entries, int size)
  181.             {
  182.                 this.entries = entries;
  183.                 this.size = size;
  184.             }
  185.            
  186.             public int Count {
  187.                 get { return size; }
  188.             }
  189.            
  190.             public object SyncRoot {
  191.                 get { return ((ICollection)entries).SyncRoot; }
  192.             }
  193.            
  194.             public bool IsSynchronized {
  195.                 get { return ((ICollection)entries).IsSynchronized; }
  196.             }
  197.            
  198.             public void CopyTo(Array array, int arrayIndex)
  199.             {
  200.                 if (array == null)
  201.                     throw new ArgumentNullException("array");
  202.                
  203.                 if (arrayIndex < 0)
  204.                     throw new ArgumentOutOfRangeException("arrayIndex");
  205.                
  206.                 Debug.Assert(array.Length >= size, "array is not big enough to hold all the items in the ICollection");
  207.                
  208.                 for (int i = 0; i < size; i++) {
  209.                     array.SetValue(entries[i].qname, arrayIndex++);
  210.                 }
  211.             }
  212.            
  213.             public IEnumerator GetEnumerator()
  214.             {
  215.                 return new XSOEnumerator(this.entries, this.size, EnumeratorType.Keys);
  216.             }
  217.         }
  218.        
  219.         //ICollection for Values
  220.         internal class ValuesCollection : ICollection
  221.         {
  222.             private List<XmlSchemaObjectEntry> entries;
  223.             int size;
  224.            
  225.             internal ValuesCollection(List<XmlSchemaObjectEntry> entries, int size)
  226.             {
  227.                 this.entries = entries;
  228.                 this.size = size;
  229.             }
  230.            
  231.             public int Count {
  232.                 get { return size; }
  233.             }
  234.            
  235.             public object SyncRoot {
  236.                 get { return ((ICollection)entries).SyncRoot; }
  237.             }
  238.            
  239.             public bool IsSynchronized {
  240.                 get { return ((ICollection)entries).IsSynchronized; }
  241.             }
  242.            
  243.             public void CopyTo(Array array, int arrayIndex)
  244.             {
  245.                 if (array == null)
  246.                     throw new ArgumentNullException("array");
  247.                
  248.                 if (arrayIndex < 0)
  249.                     throw new ArgumentOutOfRangeException("arrayIndex");
  250.                
  251.                 Debug.Assert(array.Length >= size, "array is not big enough to hold all the items in the ICollection");
  252.                
  253.                 for (int i = 0; i < size; i++) {
  254.                     array.SetValue(entries[i].xso, arrayIndex++);
  255.                 }
  256.             }
  257.            
  258.             public IEnumerator GetEnumerator()
  259.             {
  260.                 return new XSOEnumerator(this.entries, this.size, EnumeratorType.Values);
  261.             }
  262.         }
  263.        
  264.         internal class XSOEnumerator : IEnumerator
  265.         {
  266.             private List<XmlSchemaObjectEntry> entries;
  267.             private EnumeratorType enumType;
  268.            
  269.             protected int currentIndex;
  270.             protected int size;
  271.             protected XmlQualifiedName currentKey;
  272.             protected XmlSchemaObject currentValue;
  273.            
  274.            
  275.             internal XSOEnumerator(List<XmlSchemaObjectEntry> entries, int size, EnumeratorType enumType)
  276.             {
  277.                 this.entries = entries;
  278.                 this.size = size;
  279.                 this.enumType = enumType;
  280.                 currentIndex = -1;
  281.             }
  282.            
  283.             public object Current {
  284.                 get {
  285.                     if (currentIndex == -1) {
  286.                         throw new InvalidOperationException(Res.GetString(Res.Sch_EnumNotStarted, string.Empty));
  287.                     }
  288.                     if (currentIndex >= size) {
  289.                         throw new InvalidOperationException(Res.GetString(Res.Sch_EnumFinished, string.Empty));
  290.                     }
  291.                     switch (enumType) {
  292.                         case EnumeratorType.Keys:
  293.                             return currentKey;
  294.                         case EnumeratorType.Values:
  295.                            
  296.                             return currentValue;
  297.                         case EnumeratorType.DictionaryEntry:
  298.                            
  299.                             return new DictionaryEntry(currentKey, currentValue);
  300.                         default:
  301.                            
  302.                             break;
  303.                     }
  304.                     return null;
  305.                 }
  306.             }
  307.            
  308.             public bool MoveNext()
  309.             {
  310.                 if (currentIndex >= size - 1) {
  311.                     currentValue = null;
  312.                     currentKey = null;
  313.                     return false;
  314.                 }
  315.                 currentIndex++;
  316.                 currentValue = entries[currentIndex].xso;
  317.                 currentKey = entries[currentIndex].qname;
  318.                 return true;
  319.             }
  320.            
  321.             public void Reset()
  322.             {
  323.                 currentIndex = -1;
  324.                 currentValue = null;
  325.                 currentKey = null;
  326.             }
  327.         }
  328.        
  329.         internal class XSODictionaryEnumerator : XSOEnumerator, IDictionaryEnumerator
  330.         {
  331.            
  332.             internal XSODictionaryEnumerator(List<XmlSchemaObjectEntry> entries, int size, EnumeratorType enumType) : base(entries, size, enumType)
  333.             {
  334.             }
  335.            
  336.             //IDictionaryEnumerator members
  337.             public DictionaryEntry Entry {
  338.                 get {
  339.                     if (currentIndex == -1) {
  340.                         throw new InvalidOperationException(Res.GetString(Res.Sch_EnumNotStarted, string.Empty));
  341.                     }
  342.                     if (currentIndex >= size) {
  343.                         throw new InvalidOperationException(Res.GetString(Res.Sch_EnumFinished, string.Empty));
  344.                     }
  345.                     return new DictionaryEntry(currentKey, currentValue);
  346.                 }
  347.             }
  348.            
  349.             public object Key {
  350.                 get {
  351.                     if (currentIndex == -1) {
  352.                         throw new InvalidOperationException(Res.GetString(Res.Sch_EnumNotStarted, string.Empty));
  353.                     }
  354.                     if (currentIndex >= size) {
  355.                         throw new InvalidOperationException(Res.GetString(Res.Sch_EnumFinished, string.Empty));
  356.                     }
  357.                     return currentKey;
  358.                 }
  359.             }
  360.            
  361.             public object Value {
  362.                 get {
  363.                     if (currentIndex == -1) {
  364.                         throw new InvalidOperationException(Res.GetString(Res.Sch_EnumNotStarted, string.Empty));
  365.                     }
  366.                     if (currentIndex >= size) {
  367.                         throw new InvalidOperationException(Res.GetString(Res.Sch_EnumFinished, string.Empty));
  368.                     }
  369.                     return currentValue;
  370.                 }
  371.             }
  372.         }
  373.        
  374.     }
  375. }

Developer Fusion