The Labs \ Source Viewer \ SSCLI \ System.ComponentModel \ EventDescriptorCollection

  1. //------------------------------------------------------------------------------
  2. // <copyright file="EventDescriptorCollection.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.Diagnostics.CodeAnalysis;
  16. /*
  17. This class has the HostProtectionAttribute. The purpose of this attribute is to enforce host-specific programming model guidelines, not security behavior.
  18. Suppress FxCop message - BUT REVISIT IF ADDING NEW SECURITY ATTRIBUTES.
  19. */
  20. [assembly: SuppressMessage("Microsoft.Security", "CA2112:SecuredTypesShouldNotExposeFields", Scope = "type", Target = "System.ComponentModel.EventDescriptorCollection")]
  21. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection.System.Collections.IList.get_IsFixedSize():System.Boolean")]
  22. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection.System.Collections.ICollection.get_SyncRoot():System.Object")]
  23. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection.System.Collections.ICollection.get_IsSynchronized():System.Boolean")]
  24. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection.System.Collections.IList.get_IsReadOnly():System.Boolean")]
  25. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection.System.Collections.IList.Clear():System.Void")]
  26. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection.System.Collections.IEnumerable.GetEnumerator():System.Collections.IEnumerator")]
  27. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection.System.Collections.ICollection.CopyTo(System.Array,System.Int32):System.Void")]
  28. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection.System.Collections.ICollection.get_Count():System.Int32")]
  29. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection.System.Collections.IList.Contains(System.Object):System.Boolean")]
  30. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection.System.Collections.IList.Remove(System.Object):System.Void")]
  31. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection.System.Collections.IList.get_Item(System.Int32):System.Object")]
  32. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection.System.Collections.IList.set_Item(System.Int32,System.Object):System.Void")]
  33. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection.System.Collections.IList.Add(System.Object):System.Int32")]
  34. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection.System.Collections.IList.IndexOf(System.Object):System.Int32")]
  35. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection.System.Collections.IList.RemoveAt(System.Int32):System.Void")]
  36. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection.System.Collections.IList.Insert(System.Int32,System.Object):System.Void")]
  37. [assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection..ctor(System.ComponentModel.EventDescriptor[],System.Boolean)")]
  38. [assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection.get_Count():System.Int32")]
  39. [assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "System.ComponentModel.EventDescriptorCollection.GetEnumerator():System.Collections.IEnumerator")]
  40. namespace System.ComponentModel
  41. {
  42.     using System.Runtime.InteropServices;
  43.    
  44.    
  45.     using System.Diagnostics;
  46.    
  47.     using Microsoft.Win32;
  48.     using System.Collections;
  49.     using System.Globalization;
  50.    
  51.     /// <devdoc>
  52.     /// <para>
  53.     /// Represents a collection of events.
  54.     /// </para>
  55.     /// </devdoc>
  56.     [System.Runtime.InteropServices.ComVisible(true)]
  57.     [System.Security.Permissions.HostProtection(Synchronization = true)]
  58.     public class EventDescriptorCollection : ICollection, IList
  59.     {
  60.         private EventDescriptor[] events;
  61.         private string[] namedSort;
  62.         private IComparer comparer;
  63.         private bool eventsOwned = true;
  64.         private bool needSort = false;
  65.         private int eventCount;
  66.         private bool readOnly = false;
  67.        
  68.        
  69.         /// <devdoc>
  70.         /// An empty AttributeCollection that can used instead of creating a new one with no items.
  71.         /// </devdoc>
  72.         public static readonly EventDescriptorCollection Empty = new EventDescriptorCollection(null, true);
  73.        
  74.         /// <devdoc>
  75.         /// <para>
  76.         /// Initializes a new instance of the <see cref='System.ComponentModel.EventDescriptorCollection'/> class.
  77.         /// </para>
  78.         /// </devdoc>
  79.         public EventDescriptorCollection(EventDescriptor[] events)
  80.         {
  81.             this.events = events;
  82.             if (events == null) {
  83.                 this.events = new EventDescriptor[0];
  84.                 this.eventCount = 0;
  85.             }
  86.             else {
  87.                 this.eventCount = this.events.Length;
  88.             }
  89.             this.eventsOwned = true;
  90.         }
  91.        
  92.         /// <devdoc>
  93.         /// Initializes a new instance of an event descriptor collection, and allows you to mark the
  94.         /// collection as read-only so it cannot be modified.
  95.         /// </devdoc>
  96.         public EventDescriptorCollection(EventDescriptor[] events, bool readOnly) : this(events)
  97.         {
  98.             this.readOnly = readOnly;
  99.         }
  100.        
  101.         private EventDescriptorCollection(EventDescriptor[] events, int eventCount, string[] namedSort, IComparer comparer)
  102.         {
  103.             this.eventsOwned = false;
  104.             if (namedSort != null) {
  105.                 this.namedSort = (string[])namedSort.Clone();
  106.             }
  107.             this.comparer = comparer;
  108.             this.events = events;
  109.             this.eventCount = eventCount;
  110.             this.needSort = true;
  111.         }
  112.        
  113.         /// <devdoc>
  114.         /// <para>
  115.         /// Gets the number
  116.         /// of event descriptors in the collection.
  117.         /// </para>
  118.         /// </devdoc>
  119.         public int Count {
  120.             get { return eventCount; }
  121.         }
  122.        
  123.         /// <devdoc>
  124.         /// <para>Gets the event with the specified index
  125.         /// number.</para>
  126.         /// </devdoc>
  127.         public virtual EventDescriptor this[int index]
  128.         {
  129.             get {
  130.                 if (index >= eventCount) {
  131.                     throw new IndexOutOfRangeException();
  132.                 }
  133.                 EnsureEventsOwned();
  134.                 return events[index];
  135.             }
  136.         }
  137.        
  138.         /// <devdoc>
  139.         /// <para>
  140.         /// Gets the event with the specified name.
  141.         /// </para>
  142.         /// </devdoc>
  143.         public virtual EventDescriptor this[string name]
  144.         {
  145.             get { return Find(name, false); }
  146.         }
  147.        
  148.         /// <devdoc>
  149.         /// <para>[To be supplied.]</para>
  150.         /// </devdoc>
  151.         public int Add(EventDescriptor value)
  152.         {
  153.             if (readOnly) {
  154.                 throw new NotSupportedException();
  155.             }
  156.            
  157.             EnsureSize(eventCount + 1);
  158.             events[eventCount++] = value;
  159.             return eventCount - 1;
  160.         }
  161.        
  162.         /// <devdoc>
  163.         /// <para>[To be supplied.]</para>
  164.         /// </devdoc>
  165.         public void Clear()
  166.         {
  167.             if (readOnly) {
  168.                 throw new NotSupportedException();
  169.             }
  170.            
  171.             eventCount = 0;
  172.         }
  173.        
  174.         /// <devdoc>
  175.         /// <para>[To be supplied.]</para>
  176.         /// </devdoc>
  177.         public bool Contains(EventDescriptor value)
  178.         {
  179.             return IndexOf(value) >= 0;
  180.         }
  181.        
  182.         /// <internalonly/>
  183.         void ICollection.CopyTo(Array array, int index)
  184.         {
  185.             EnsureEventsOwned();
  186.             Array.Copy(events, 0, array, index, Count);
  187.         }
  188.        
  189.         private void EnsureEventsOwned()
  190.         {
  191.             if (!eventsOwned) {
  192.                 eventsOwned = true;
  193.                 if (events != null) {
  194.                     EventDescriptor[] newEvents = new EventDescriptor[Count];
  195.                     Array.Copy(events, 0, newEvents, 0, Count);
  196.                     this.events = newEvents;
  197.                 }
  198.             }
  199.            
  200.             if (needSort) {
  201.                 needSort = false;
  202.                 InternalSort(this.namedSort);
  203.             }
  204.         }
  205.        
  206.         private void EnsureSize(int sizeNeeded)
  207.         {
  208.            
  209.             if (sizeNeeded <= events.Length) {
  210.                 return;
  211.             }
  212.            
  213.             if (events == null || events.Length == 0) {
  214.                 eventCount = 0;
  215.                 events = new EventDescriptor[sizeNeeded];
  216.                 return;
  217.             }
  218.            
  219.             EnsureEventsOwned();
  220.            
  221.             int newSize = Math.Max(sizeNeeded, events.Length * 2);
  222.             EventDescriptor[] newEvents = new EventDescriptor[newSize];
  223.             Array.Copy(events, 0, newEvents, 0, eventCount);
  224.             events = newEvents;
  225.         }
  226.        
  227.         /// <devdoc>
  228.         /// <para>
  229.         /// Gets the description of the event with the specified
  230.         /// name
  231.         /// in the collection.
  232.         /// </para>
  233.         /// </devdoc>
  234.         public virtual EventDescriptor Find(string name, bool ignoreCase)
  235.         {
  236.             EventDescriptor p = null;
  237.            
  238.             if (ignoreCase) {
  239.                 for (int i = 0; i < Count; i++) {
  240.                     if (String.Equals(events[i].Name, name, StringComparison.OrdinalIgnoreCase)) {
  241.                         p = events[i];
  242.                         break;
  243.                     }
  244.                 }
  245.             }
  246.             else {
  247.                 for (int i = 0; i < Count; i++) {
  248.                     if (String.Equals(events[i].Name, name, StringComparison.Ordinal)) {
  249.                         p = events[i];
  250.                         break;
  251.                     }
  252.                 }
  253.             }
  254.            
  255.             return p;
  256.         }
  257.        
  258.         /// <devdoc>
  259.         /// <para>[To be supplied.]</para>
  260.         /// </devdoc>
  261.         public int IndexOf(EventDescriptor value)
  262.         {
  263.             return Array.IndexOf(events, value, 0, eventCount);
  264.         }
  265.        
  266.         /// <devdoc>
  267.         /// <para>[To be supplied.]</para>
  268.         /// </devdoc>
  269.         public void Insert(int index, EventDescriptor value)
  270.         {
  271.             if (readOnly) {
  272.                 throw new NotSupportedException();
  273.             }
  274.            
  275.             EnsureSize(eventCount + 1);
  276.             if (index < eventCount) {
  277.                 Array.Copy(events, index, events, index + 1, eventCount - index);
  278.             }
  279.             events[index] = value;
  280.             eventCount++;
  281.         }
  282.        
  283.         /// <devdoc>
  284.         /// <para>[To be supplied.]</para>
  285.         /// </devdoc>
  286.         public void Remove(EventDescriptor value)
  287.         {
  288.             if (readOnly) {
  289.                 throw new NotSupportedException();
  290.             }
  291.            
  292.             int index = IndexOf(value);
  293.            
  294.             if (index != -1) {
  295.                 RemoveAt(index);
  296.             }
  297.         }
  298.        
  299.         /// <devdoc>
  300.         /// <para>[To be supplied.]</para>
  301.         /// </devdoc>
  302.         public void RemoveAt(int index)
  303.         {
  304.             if (readOnly) {
  305.                 throw new NotSupportedException();
  306.             }
  307.            
  308.             if (index < eventCount - 1) {
  309.                 Array.Copy(events, index + 1, events, index, eventCount - index - 1);
  310.             }
  311.             events[eventCount - 1] = null;
  312.             eventCount--;
  313.         }
  314.        
  315.         /// <devdoc>
  316.         /// <para>
  317.         /// Gets an enumerator for this <see cref='System.ComponentModel.EventDescriptorCollection'/>.
  318.         /// </para>
  319.         /// </devdoc>
  320.         public IEnumerator GetEnumerator()
  321.         {
  322.             // we can only return an enumerator on the events we actually have...
  323.             if (events.Length == eventCount) {
  324.                 return events.GetEnumerator();
  325.             }
  326.             else {
  327.                 return new ArraySubsetEnumerator(events, eventCount);
  328.             }
  329.         }
  330.        
  331.         /// <devdoc>
  332.         /// <para>
  333.         /// Sorts the members of this EventDescriptorCollection, using the default sort for this collection,
  334.         /// which is usually alphabetical.
  335.         /// </para>
  336.         /// </devdoc>
  337.         public virtual EventDescriptorCollection Sort()
  338.         {
  339.             return new EventDescriptorCollection(this.events, this.eventCount, this.namedSort, this.comparer);
  340.         }
  341.        
  342.        
  343.         /// <devdoc>
  344.         /// <para>
  345.         /// Sorts the members of this EventDescriptorCollection. Any specified NamedSort arguments will
  346.         /// be applied first, followed by sort using the specified IComparer.
  347.         /// </para>
  348.         /// </devdoc>
  349.         public virtual EventDescriptorCollection Sort(string[] names)
  350.         {
  351.             return new EventDescriptorCollection(this.events, this.eventCount, names, this.comparer);
  352.         }
  353.        
  354.         /// <devdoc>
  355.         /// <para>
  356.         /// Sorts the members of this EventDescriptorCollection. Any specified NamedSort arguments will
  357.         /// be applied first, followed by sort using the specified IComparer.
  358.         /// </para>
  359.         /// </devdoc>
  360.         public virtual EventDescriptorCollection Sort(string[] names, IComparer comparer)
  361.         {
  362.             return new EventDescriptorCollection(this.events, this.eventCount, names, comparer);
  363.         }
  364.        
  365.         /// <devdoc>
  366.         /// <para>
  367.         /// Sorts the members of this EventDescriptorCollection, using the specified IComparer to compare,
  368.         /// the EventDescriptors contained in the collection.
  369.         /// </para>
  370.         /// </devdoc>
  371.         public virtual EventDescriptorCollection Sort(IComparer comparer)
  372.         {
  373.             return new EventDescriptorCollection(this.events, this.eventCount, this.namedSort, comparer);
  374.         }
  375.        
  376.         /// <devdoc>
  377.         /// <para>
  378.         /// Sorts the members of this EventDescriptorCollection. Any specified NamedSort arguments will
  379.         /// be applied first, followed by sort using the specified IComparer.
  380.         /// </para>
  381.         /// </devdoc>
  382.         protected void InternalSort(string[] names)
  383.         {
  384.             if (events == null || events.Length == 0) {
  385.                 return;
  386.             }
  387.            
  388.             this.InternalSort(this.comparer);
  389.            
  390.             if (names != null && names.Length > 0) {
  391.                
  392.                 ArrayList eventArrayList = new ArrayList(events);
  393.                 int foundCount = 0;
  394.                 int eventCount = events.Length;
  395.                
  396.                 for (int i = 0; i < names.Length; i++) {
  397.                     for (int j = 0; j < eventCount; j++) {
  398.                         EventDescriptor currentEvent = (EventDescriptor)eventArrayList[j];
  399.                        
  400.                         // Found a matching event. Here, we add it to our array. We also
  401.                         // mark it as null in our array list so we don't add it twice later.
  402.                         //
  403.                         if (currentEvent != null && currentEvent.Name.Equals(names[i])) {
  404.                             events[foundCount++] = currentEvent;
  405.                             eventArrayList[j] = null;
  406.                             break;
  407.                         }
  408.                     }
  409.                 }
  410.                
  411.                 // At this point we have filled in the first "foundCount" number of propeties, one for each
  412.                 // name in our name array. If a name didn't match, then it is ignored. Next, we must fill
  413.                 // in the rest of the properties. We now have a sparse array containing the remainder, so
  414.                 // it's easy.
  415.                 //
  416.                 for (int i = 0; i < eventCount; i++) {
  417.                     if (eventArrayList[i] != null) {
  418.                         events[foundCount++] = (EventDescriptor)eventArrayList[i];
  419.                     }
  420.                 }
  421.                
  422.                 Debug.Assert(foundCount == eventCount, "We did not completely fill our event array");
  423.             }
  424.         }
  425.        
  426.         /// <devdoc>
  427.         /// <para>
  428.         /// Sorts the members of this EventDescriptorCollection using the specified IComparer.
  429.         /// </para>
  430.         /// </devdoc>
  431.         protected void InternalSort(IComparer sorter)
  432.         {
  433.             if (sorter == null) {
  434.                 TypeDescriptor.SortDescriptorArray(this);
  435.             }
  436.             else {
  437.                 Array.Sort(events, sorter);
  438.             }
  439.         }
  440.        
  441.         /// <internalonly/>
  442.         int ICollection.Count {
  443.             get { return Count; }
  444.         }
  445.        
  446.        
  447.         /// <internalonly/>
  448.         bool ICollection.IsSynchronized {
  449.             get { return false; }
  450.         }
  451.        
  452.         /// <internalonly/>
  453.         object ICollection.SyncRoot {
  454.             get { return null; }
  455.         }
  456.        
  457.         /// <internalonly/>
  458.         IEnumerator IEnumerable.GetEnumerator()
  459.         {
  460.             return GetEnumerator();
  461.         }
  462.        
  463.         /// <internalonly/>
  464.         object IList.this[int index]
  465.         {
  466.             get { return this[index]; }
  467.             set {
  468.                 if (readOnly) {
  469.                     throw new NotSupportedException();
  470.                 }
  471.                
  472.                 if (index >= eventCount) {
  473.                     throw new IndexOutOfRangeException();
  474.                 }
  475.                 EnsureEventsOwned();
  476.                 events[index] = (EventDescriptor)value;
  477.             }
  478.         }
  479.        
  480.         /// <internalonly/>
  481.         int IList.Add(object value)
  482.         {
  483.             return Add((EventDescriptor)value);
  484.         }
  485.        
  486.         /// <internalonly/>
  487.         void IList.Clear()
  488.         {
  489.             Clear();
  490.         }
  491.        
  492.         /// <internalonly/>
  493.         bool IList.Contains(object value)
  494.         {
  495.             return Contains((EventDescriptor)value);
  496.         }
  497.        
  498.         /// <internalonly/>
  499.         int IList.IndexOf(object value)
  500.         {
  501.             return IndexOf((EventDescriptor)value);
  502.         }
  503.        
  504.         /// <internalonly/>
  505.         void IList.Insert(int index, object value)
  506.         {
  507.             Insert(index, (EventDescriptor)value);
  508.         }
  509.        
  510.         /// <internalonly/>
  511.         void IList.Remove(object value)
  512.         {
  513.             Remove((EventDescriptor)value);
  514.         }
  515.        
  516.         /// <internalonly/>
  517.         void IList.RemoveAt(int index)
  518.         {
  519.             RemoveAt(index);
  520.         }
  521.        
  522.         /// <internalonly/>
  523.         bool IList.IsReadOnly {
  524.             get { return readOnly; }
  525.         }
  526.        
  527.         /// <internalonly/>
  528.         bool IList.IsFixedSize {
  529.             get { return readOnly; }
  530.         }
  531.     }
  532. }

Developer Fusion