using System; using System.Diagnostics; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Runtime.Serialization; namespace System.Collections { /// Represents a collection of key/value pairs that are organized based on the hash code of the key. /// 1 // Token: 0x0200012A RID: 298 [DebuggerDisplay("Count={Count}")] [ComVisible(true)] [DebuggerTypeProxy(typeof(CollectionDebuggerView))] [Serializable] public class Hashtable : IEnumerable, ICloneable, ISerializable, ICollection, IDictionary, IDeserializationCallback { /// Initializes a new, empty instance of the class using the default initial capacity, load factor, hash code provider, and comparer. // Token: 0x06000F79 RID: 3961 RVA: 0x00040A50 File Offset: 0x0003EC50 public Hashtable() : this(0, 1f) { } /// Initializes a new, empty instance of the class using the specified initial capacity, load factor, hash code provider, and comparer. /// The approximate number of elements that the object can initially contain. /// A number in the range from 0.1 through 1.0 that is multiplied by the default value which provides the best performance. The result is the maximum ratio of elements to buckets. /// The object that supplies the hash codes for all keys in the .-or- null to use the default hash code provider, which is each key's implementation of . /// The object to use to determine whether two keys are equal.-or- null to use the default comparer, which is each key's implementation of . /// /// is less than zero.-or- is less than 0.1.-or- is greater than 1.0. // Token: 0x06000F7A RID: 3962 RVA: 0x00040A60 File Offset: 0x0003EC60 [Obsolete("Please use Hashtable(int, float, IEqualityComparer) instead")] public Hashtable(int capacity, float loadFactor, IHashCodeProvider hcp, IComparer comparer) { if (capacity < 0) { throw new ArgumentOutOfRangeException("capacity", "negative capacity"); } if (loadFactor < 0.1f || loadFactor > 1f || float.IsNaN(loadFactor)) { throw new ArgumentOutOfRangeException("loadFactor", "load factor"); } if (capacity == 0) { capacity++; } this.loadFactor = 0.75f * loadFactor; double num = (double)((float)capacity / this.loadFactor); if (num > 2147483647.0) { throw new ArgumentException("Size is too big"); } int num2 = (int)num; num2 = Hashtable.ToPrime(num2); this.SetTable(new Hashtable.Slot[num2], new int[num2]); this.hcp = hcp; this.comparer = comparer; this.inUse = 0; this.modificationCount = 0; } /// Initializes a new, empty instance of the class using the specified initial capacity and load factor, and the default hash code provider and comparer. /// The approximate number of elements that the object can initially contain. /// A number in the range from 0.1 through 1.0 that is multiplied by the default value which provides the best performance. The result is the maximum ratio of elements to buckets. /// /// is less than zero.-or- is less than 0.1.-or- is greater than 1.0. /// /// is causing an overflow. // Token: 0x06000F7B RID: 3963 RVA: 0x00040B34 File Offset: 0x0003ED34 public Hashtable(int capacity, float loadFactor) : this(capacity, loadFactor, null, null) { } /// Initializes a new, empty instance of the class using the specified initial capacity, and the default load factor, hash code provider, and comparer. /// The approximate number of elements that the object can initially contain. /// /// is less than zero. // Token: 0x06000F7C RID: 3964 RVA: 0x00040B40 File Offset: 0x0003ED40 public Hashtable(int capacity) : this(capacity, 1f) { } // Token: 0x06000F7D RID: 3965 RVA: 0x00040B50 File Offset: 0x0003ED50 internal Hashtable(Hashtable source) { this.inUse = source.inUse; this.loadFactor = source.loadFactor; this.table = (Hashtable.Slot[])source.table.Clone(); this.hashes = (int[])source.hashes.Clone(); this.threshold = source.threshold; this.hcpRef = source.hcpRef; this.comparerRef = source.comparerRef; this.equalityComparer = source.equalityComparer; } /// Initializes a new, empty instance of the class using the specified initial capacity, hash code provider, comparer, and the default load factor. /// The approximate number of elements that the object can initially contain. /// The object that supplies the hash codes for all keys in the .-or- null to use the default hash code provider, which is each key's implementation of . /// The object to use to determine whether two keys are equal.-or- null to use the default comparer, which is each key's implementation of . /// /// is less than zero. // Token: 0x06000F7E RID: 3966 RVA: 0x00040BD8 File Offset: 0x0003EDD8 [Obsolete("Please use Hashtable(int, IEqualityComparer) instead")] public Hashtable(int capacity, IHashCodeProvider hcp, IComparer comparer) : this(capacity, 1f, hcp, comparer) { } /// Initializes a new instance of the class by copying the elements from the specified dictionary to the new object. The new object has an initial capacity equal to the number of elements copied, and uses the specified load factor, hash code provider, and comparer. /// The object to copy to a new object. /// A number in the range from 0.1 through 1.0 that is multiplied by the default value which provides the best performance. The result is the maximum ratio of elements to buckets. /// The object that supplies the hash codes for all keys in the .-or- null to use the default hash code provider, which is each key's implementation of . /// The object to use to determine whether two keys are equal.-or- null to use the default comparer, which is each key's implementation of . /// /// is null. /// /// is less than 0.1.-or- is greater than 1.0. // Token: 0x06000F7F RID: 3967 RVA: 0x00040BE8 File Offset: 0x0003EDE8 [Obsolete("Please use Hashtable(IDictionary, float, IEqualityComparer) instead")] public Hashtable(IDictionary d, float loadFactor, IHashCodeProvider hcp, IComparer comparer) : this((d == null) ? 0 : d.Count, loadFactor, hcp, comparer) { if (d == null) { throw new ArgumentNullException("dictionary"); } IDictionaryEnumerator enumerator = d.GetEnumerator(); while (enumerator.MoveNext()) { this.Add(enumerator.Key, enumerator.Value); } } /// Initializes a new instance of the class by copying the elements from the specified dictionary to the new object. The new object has an initial capacity equal to the number of elements copied, and uses the specified load factor, and the default hash code provider and comparer. /// The object to copy to a new object. /// A number in the range from 0.1 through 1.0 that is multiplied by the default value which provides the best performance. The result is the maximum ratio of elements to buckets. /// /// is null. /// /// is less than 0.1.-or- is greater than 1.0. // Token: 0x06000F80 RID: 3968 RVA: 0x00040C4C File Offset: 0x0003EE4C public Hashtable(IDictionary d, float loadFactor) : this(d, loadFactor, null, null) { } /// Initializes a new instance of the class by copying the elements from the specified dictionary to the new object. The new object has an initial capacity equal to the number of elements copied, and uses the default load factor, hash code provider, and comparer. /// The object to copy to a new object. /// /// is null. // Token: 0x06000F81 RID: 3969 RVA: 0x00040C58 File Offset: 0x0003EE58 public Hashtable(IDictionary d) : this(d, 1f) { } /// Initializes a new instance of the class by copying the elements from the specified dictionary to the new object. The new object has an initial capacity equal to the number of elements copied, and uses the default load factor, and the specified hash code provider and comparer. /// The object to copy to a new object. /// The object that supplies the hash codes for all keys in the .-or- null to use the default hash code provider, which is each key's implementation of . /// The object to use to determine whether two keys are equal.-or- null to use the default comparer, which is each key's implementation of . /// /// is null. // Token: 0x06000F82 RID: 3970 RVA: 0x00040C68 File Offset: 0x0003EE68 [Obsolete("Please use Hashtable(IDictionary, IEqualityComparer) instead")] public Hashtable(IDictionary d, IHashCodeProvider hcp, IComparer comparer) : this(d, 1f, hcp, comparer) { } /// Initializes a new, empty instance of the class using the default initial capacity and load factor, and the specified hash code provider and comparer. /// The object that supplies the hash codes for all keys in the object.-or- null to use the default hash code provider, which is each key's implementation of . /// The object to use to determine whether two keys are equal.-or- null to use the default comparer, which is each key's implementation of . // Token: 0x06000F83 RID: 3971 RVA: 0x00040C78 File Offset: 0x0003EE78 [Obsolete("Please use Hashtable(IEqualityComparer) instead")] public Hashtable(IHashCodeProvider hcp, IComparer comparer) : this(1, 1f, hcp, comparer) { } /// Initializes a new, empty instance of the class that is serializable using the specified and objects. /// A object containing the information required to serialize the object. /// A object containing the source and destination of the serialized stream associated with the . /// /// is null. // Token: 0x06000F84 RID: 3972 RVA: 0x00040C88 File Offset: 0x0003EE88 public Hashtable(SerializationInfo info, StreamingContext context) { this.serializationInfo = info; } /// Initializes a new instance of the class by copying the elements from the specified dictionary to a new object. The new object has an initial capacity equal to the number of elements copied, and uses the default load factor and the specified object. /// The object to copy to a new object. /// The object that defines the hash code provider and the comparer to use with the .-or- null to use the default hash code provider and the default comparer. The default hash code provider is each key's implementation of and the default comparer is each key's implementation of . /// /// is null. // Token: 0x06000F85 RID: 3973 RVA: 0x00040C98 File Offset: 0x0003EE98 public Hashtable(IDictionary d, IEqualityComparer equalityComparer) : this(d, 1f, equalityComparer) { } /// Initializes a new instance of the class by copying the elements from the specified dictionary to the new object. The new object has an initial capacity equal to the number of elements copied, and uses the specified load factor and object. /// The object to copy to a new object. /// A number in the range from 0.1 through 1.0 that is multiplied by the default value which provides the best performance. The result is the maximum ratio of elements to buckets. /// The object that defines the hash code provider and the comparer to use with the .-or- null to use the default hash code provider and the default comparer. The default hash code provider is each key's implementation of and the default comparer is each key's implementation of . /// /// is null. /// /// is less than 0.1.-or- is greater than 1.0. // Token: 0x06000F86 RID: 3974 RVA: 0x00040CA8 File Offset: 0x0003EEA8 public Hashtable(IDictionary d, float loadFactor, IEqualityComparer equalityComparer) : this(d, loadFactor) { this.equalityComparer = equalityComparer; } /// Initializes a new, empty instance of the class using the default initial capacity and load factor, and the specified object. /// The object that defines the hash code provider and the comparer to use with the object.-or- null to use the default hash code provider and the default comparer. The default hash code provider is each key's implementation of and the default comparer is each key's implementation of . // Token: 0x06000F87 RID: 3975 RVA: 0x00040CBC File Offset: 0x0003EEBC public Hashtable(IEqualityComparer equalityComparer) : this(1, 1f, equalityComparer) { } /// Initializes a new, empty instance of the class using the specified initial capacity and , and the default load factor. /// The approximate number of elements that the object can initially contain. /// The object that defines the hash code provider and the comparer to use with the .-or- null to use the default hash code provider and the default comparer. The default hash code provider is each key's implementation of and the default comparer is each key's implementation of . /// /// is less than zero. // Token: 0x06000F88 RID: 3976 RVA: 0x00040CCC File Offset: 0x0003EECC public Hashtable(int capacity, IEqualityComparer equalityComparer) : this(capacity, 1f, equalityComparer) { } /// Initializes a new, empty instance of the class using the specified initial capacity, load factor, and object. /// The approximate number of elements that the object can initially contain. /// A number in the range from 0.1 through 1.0 that is multiplied by the default value which provides the best performance. The result is the maximum ratio of elements to buckets. /// The object that defines the hash code provider and the comparer to use with the .-or- null to use the default hash code provider and the default comparer. The default hash code provider is each key's implementation of and the default comparer is each key's implementation of . /// /// is less than zero.-or- is less than 0.1.-or- is greater than 1.0. // Token: 0x06000F89 RID: 3977 RVA: 0x00040CDC File Offset: 0x0003EEDC public Hashtable(int capacity, float loadFactor, IEqualityComparer equalityComparer) : this(capacity, loadFactor) { this.equalityComparer = equalityComparer; } /// Returns an enumerator that iterates through a collection. /// An that can be used to iterate through the collection. // Token: 0x06000F8B RID: 3979 RVA: 0x00040D0C File Offset: 0x0003EF0C IEnumerator IEnumerable.GetEnumerator() { return new Hashtable.Enumerator(this, Hashtable.EnumeratorMode.ENTRY_MODE); } /// Gets or sets the to use for the . /// The to use for the . /// The property is set to a value, but the hash table was created using an . // Token: 0x17000270 RID: 624 // (get) Token: 0x06000F8D RID: 3981 RVA: 0x00040D24 File Offset: 0x0003EF24 // (set) Token: 0x06000F8C RID: 3980 RVA: 0x00040D18 File Offset: 0x0003EF18 [Obsolete("Please use EqualityComparer property.")] protected IComparer comparer { get { return this.comparerRef; } set { this.comparerRef = value; } } /// Gets or sets the object that can dispense hash codes. /// The object that can dispense hash codes. /// The property is set to a value, but the hash table was created using an . // Token: 0x17000271 RID: 625 // (get) Token: 0x06000F8F RID: 3983 RVA: 0x00040D38 File Offset: 0x0003EF38 // (set) Token: 0x06000F8E RID: 3982 RVA: 0x00040D2C File Offset: 0x0003EF2C [Obsolete("Please use EqualityComparer property.")] protected IHashCodeProvider hcp { get { return this.hcpRef; } set { this.hcpRef = value; } } /// Gets the to use for the . /// The to use for the . /// The property is set to a value, but the hash table was created using an and an . // Token: 0x17000272 RID: 626 // (get) Token: 0x06000F90 RID: 3984 RVA: 0x00040D40 File Offset: 0x0003EF40 protected IEqualityComparer EqualityComparer { get { return this.equalityComparer; } } /// Gets the number of key/value pairs contained in the . /// The number of key/value pairs contained in the . /// 1 // Token: 0x17000273 RID: 627 // (get) Token: 0x06000F91 RID: 3985 RVA: 0x00040D48 File Offset: 0x0003EF48 public virtual int Count { get { return this.inUse; } } /// Gets a value indicating whether access to the is synchronized (thread safe). /// true if access to the is synchronized (thread safe); otherwise, false. The default is false. /// 2 // Token: 0x17000274 RID: 628 // (get) Token: 0x06000F92 RID: 3986 RVA: 0x00040D50 File Offset: 0x0003EF50 public virtual bool IsSynchronized { get { return false; } } /// Gets an object that can be used to synchronize access to the . /// An object that can be used to synchronize access to the . /// 2 // Token: 0x17000275 RID: 629 // (get) Token: 0x06000F93 RID: 3987 RVA: 0x00040D54 File Offset: 0x0003EF54 public virtual object SyncRoot { get { return this; } } /// Gets a value indicating whether the has a fixed size. /// true if the has a fixed size; otherwise, false. The default is false. /// 2 // Token: 0x17000276 RID: 630 // (get) Token: 0x06000F94 RID: 3988 RVA: 0x00040D58 File Offset: 0x0003EF58 public virtual bool IsFixedSize { get { return false; } } /// Gets a value indicating whether the is read-only. /// true if the is read-only; otherwise, false. The default is false. /// 2 // Token: 0x17000277 RID: 631 // (get) Token: 0x06000F95 RID: 3989 RVA: 0x00040D5C File Offset: 0x0003EF5C public virtual bool IsReadOnly { get { return false; } } /// Gets an containing the keys in the . /// An containing the keys in the . /// 1 // Token: 0x17000278 RID: 632 // (get) Token: 0x06000F96 RID: 3990 RVA: 0x00040D60 File Offset: 0x0003EF60 public virtual ICollection Keys { get { if (this.hashKeys == null) { this.hashKeys = new Hashtable.HashKeys(this); } return this.hashKeys; } } /// Gets an containing the values in the . /// An containing the values in the . /// 1 // Token: 0x17000279 RID: 633 // (get) Token: 0x06000F97 RID: 3991 RVA: 0x00040D80 File Offset: 0x0003EF80 public virtual ICollection Values { get { if (this.hashValues == null) { this.hashValues = new Hashtable.HashValues(this); } return this.hashValues; } } /// Gets or sets the value associated with the specified key. /// The value associated with the specified key. If the specified key is not found, attempting to get it returns null, and attempting to set it creates a new element using the specified key. /// The key whose value to get or set. /// /// is null. /// The property is set and the is read-only.-or- The property is set, does not exist in the collection, and the has a fixed size. /// 2 // Token: 0x1700027A RID: 634 public virtual object this[object key] { get { if (key == null) { throw new ArgumentNullException("key", "null key"); } Hashtable.Slot[] array = this.table; int[] array2 = this.hashes; uint num = (uint)array.Length; int num2 = this.GetHash(key) & int.MaxValue; uint num3 = (uint)num2; uint num4 = (uint)(((num2 >> 5) + 1) % (int)(num - 1U) + 1); for (uint num5 = num; num5 > 0U; num5 -= 1U) { num3 %= num; Hashtable.Slot slot = array[(int)((UIntPtr)num3)]; int num6 = array2[(int)((UIntPtr)num3)]; object key2 = slot.key; if (key2 == null) { break; } if (key2 == key || ((num6 & 2147483647) == num2 && this.KeyEquals(key, key2))) { return slot.value; } if ((num6 & -2147483648) == 0) { break; } num3 += num4; } return null; } set { this.PutImpl(key, value, true); } } /// Copies the elements to a one-dimensional instance at the specified index. /// The one-dimensional that is the destination of the objects copied from . The must have zero-based indexing. /// The zero-based index in at which copying begins. /// /// is null. /// /// is less than zero. /// /// is multidimensional.-or- The number of elements in the source is greater than the available space from to the end of the destination . /// The type of the source cannot be cast automatically to the type of the destination . /// 2 // Token: 0x06000F9A RID: 3994 RVA: 0x00040E90 File Offset: 0x0003F090 public virtual void CopyTo(Array array, int arrayIndex) { if (array == null) { throw new ArgumentNullException("array"); } if (arrayIndex < 0) { throw new ArgumentOutOfRangeException("arrayIndex"); } if (array.Rank > 1) { throw new ArgumentException("array is multidimensional"); } if (array.Length > 0 && arrayIndex >= array.Length) { throw new ArgumentException("arrayIndex is equal to or greater than array.Length"); } if (arrayIndex + this.inUse > array.Length) { throw new ArgumentException("Not enough room from arrayIndex to end of array for this Hashtable"); } IDictionaryEnumerator enumerator = this.GetEnumerator(); int num = arrayIndex; while (enumerator.MoveNext()) { array.SetValue(enumerator.Entry, num++); } } /// Adds an element with the specified key and value into the . /// The key of the element to add. /// The value of the element to add. The value can be null. /// /// is null. /// An element with the same key already exists in the . /// The is read-only.-or- The has a fixed size. /// 1 // Token: 0x06000F9B RID: 3995 RVA: 0x00040F48 File Offset: 0x0003F148 public virtual void Add(object key, object value) { this.PutImpl(key, value, false); } /// Removes all elements from the . /// The is read-only. /// 1 // Token: 0x06000F9C RID: 3996 RVA: 0x00040F54 File Offset: 0x0003F154 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] public virtual void Clear() { for (int i = 0; i < this.table.Length; i++) { this.table[i].key = null; this.table[i].value = null; this.hashes[i] = 0; } this.inUse = 0; this.modificationCount++; } /// Determines whether the contains a specific key. /// true if the contains an element with the specified key; otherwise, false. /// The key to locate in the . /// /// is null. /// 1 // Token: 0x06000F9D RID: 3997 RVA: 0x00040FBC File Offset: 0x0003F1BC public virtual bool Contains(object key) { return this.Find(key) >= 0; } /// Returns an that iterates through the . /// An for the . /// 2 // Token: 0x06000F9E RID: 3998 RVA: 0x00040FCC File Offset: 0x0003F1CC public virtual IDictionaryEnumerator GetEnumerator() { return new Hashtable.Enumerator(this, Hashtable.EnumeratorMode.ENTRY_MODE); } /// Removes the element with the specified key from the . /// The key of the element to remove. /// /// is null. /// The is read-only.-or- The has a fixed size. /// 1 // Token: 0x06000F9F RID: 3999 RVA: 0x00040FD8 File Offset: 0x0003F1D8 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] public virtual void Remove(object key) { int num = this.Find(key); if (num >= 0) { Hashtable.Slot[] array = this.table; int num2 = this.hashes[num]; num2 &= int.MinValue; this.hashes[num] = num2; array[num].key = ((num2 == 0) ? null : Hashtable.KeyMarker.Removed); array[num].value = null; this.inUse--; this.modificationCount++; } } /// Determines whether the contains a specific key. /// true if the contains an element with the specified key; otherwise, false. /// The key to locate in the . /// /// is null. /// 1 // Token: 0x06000FA0 RID: 4000 RVA: 0x0004105C File Offset: 0x0003F25C public virtual bool ContainsKey(object key) { return this.Contains(key); } /// Determines whether the contains a specific value. /// true if the contains an element with the specified ; otherwise, false. /// The value to locate in the . The value can be null. /// 1 // Token: 0x06000FA1 RID: 4001 RVA: 0x00041068 File Offset: 0x0003F268 public virtual bool ContainsValue(object value) { int num = this.table.Length; Hashtable.Slot[] array = this.table; if (value == null) { for (int i = 0; i < num; i++) { Hashtable.Slot slot = array[i]; if (slot.key != null && slot.key != Hashtable.KeyMarker.Removed && slot.value == null) { return true; } } } else { for (int j = 0; j < num; j++) { Hashtable.Slot slot2 = array[j]; if (slot2.key != null && slot2.key != Hashtable.KeyMarker.Removed && value.Equals(slot2.value)) { return true; } } } return false; } /// Creates a shallow copy of the . /// A shallow copy of the . /// 1 // Token: 0x06000FA2 RID: 4002 RVA: 0x00041134 File Offset: 0x0003F334 public virtual object Clone() { return new Hashtable(this); } /// Implements the interface and returns the data needed to serialize the . /// A object containing the information required to serialize the . /// A object containing the source and destination of the serialized stream associated with the . /// /// is null. /// The collection was modified. /// 2 // Token: 0x06000FA3 RID: 4003 RVA: 0x0004113C File Offset: 0x0003F33C public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { if (info == null) { throw new ArgumentNullException("info"); } info.AddValue("LoadFactor", this.loadFactor); info.AddValue("Version", this.modificationCount); if (this.equalityComparer != null) { info.AddValue("KeyComparer", this.equalityComparer); } else { info.AddValue("Comparer", this.comparerRef); } if (this.hcpRef != null) { info.AddValue("HashCodeProvider", this.hcpRef); } info.AddValue("HashSize", this.table.Length); object[] array = new object[this.inUse]; this.CopyToArray(array, 0, Hashtable.EnumeratorMode.KEY_MODE); object[] array2 = new object[this.inUse]; this.CopyToArray(array2, 0, Hashtable.EnumeratorMode.VALUE_MODE); info.AddValue("Keys", array); info.AddValue("Values", array2); info.AddValue("equalityComparer", this.equalityComparer); } /// Implements the interface and raises the deserialization event when the deserialization is complete. /// The source of the deserialization event. /// The object associated with the current is invalid. /// 2 // Token: 0x06000FA4 RID: 4004 RVA: 0x00041230 File Offset: 0x0003F430 [MonoTODO("Serialize equalityComparer")] public virtual void OnDeserialization(object sender) { if (this.serializationInfo == null) { return; } this.loadFactor = (float)this.serializationInfo.GetValue("LoadFactor", typeof(float)); this.modificationCount = (int)this.serializationInfo.GetValue("Version", typeof(int)); try { this.equalityComparer = (IEqualityComparer)this.serializationInfo.GetValue("KeyComparer", typeof(object)); } catch { } if (this.equalityComparer == null) { this.comparerRef = (IComparer)this.serializationInfo.GetValue("Comparer", typeof(object)); } try { this.hcpRef = (IHashCodeProvider)this.serializationInfo.GetValue("HashCodeProvider", typeof(object)); } catch { } int num = (int)this.serializationInfo.GetValue("HashSize", typeof(int)); object[] array = (object[])this.serializationInfo.GetValue("Keys", typeof(object[])); object[] array2 = (object[])this.serializationInfo.GetValue("Values", typeof(object[])); if (array.Length != array2.Length) { throw new SerializationException("Keys and values of uneven size"); } num = Hashtable.ToPrime(num); this.SetTable(new Hashtable.Slot[num], new int[num]); for (int i = 0; i < array.Length; i++) { this.Add(array[i], array2[i]); } this.AdjustThreshold(); this.serializationInfo = null; } /// Returns a synchronized (thread safe) wrapper for the . /// A synchronized (thread safe) wrapper for the . /// The to synchronize. /// /// is null. /// 1 // Token: 0x06000FA5 RID: 4005 RVA: 0x00041414 File Offset: 0x0003F614 public static Hashtable Synchronized(Hashtable table) { if (table == null) { throw new ArgumentNullException("table"); } return new Hashtable.SyncHashtable(table); } /// Returns the hash code for the specified key. /// The hash code for . /// The for which a hash code is to be returned. /// /// is null. // Token: 0x06000FA6 RID: 4006 RVA: 0x00041430 File Offset: 0x0003F630 protected virtual int GetHash(object key) { if (this.equalityComparer != null) { return this.equalityComparer.GetHashCode(key); } if (this.hcpRef == null) { return key.GetHashCode(); } return this.hcpRef.GetHashCode(key); } /// Compares a specific with a specific key in the . /// true if and are equal; otherwise, false. /// The to compare with . /// The key in the to compare with . /// /// is null.-or- is null. // Token: 0x06000FA7 RID: 4007 RVA: 0x00041474 File Offset: 0x0003F674 protected virtual bool KeyEquals(object item, object key) { if (key == Hashtable.KeyMarker.Removed) { return false; } if (this.equalityComparer != null) { return this.equalityComparer.Equals(item, key); } if (this.comparerRef == null) { return item.Equals(key); } return this.comparerRef.Compare(item, key) == 0; } // Token: 0x06000FA8 RID: 4008 RVA: 0x000414CC File Offset: 0x0003F6CC private void AdjustThreshold() { int num = this.table.Length; this.threshold = (int)((float)num * this.loadFactor); if (this.threshold >= num) { this.threshold = num - 1; } } // Token: 0x06000FA9 RID: 4009 RVA: 0x00041508 File Offset: 0x0003F708 private void SetTable(Hashtable.Slot[] table, int[] hashes) { if (table == null) { throw new ArgumentNullException("table"); } this.table = table; this.hashes = hashes; this.AdjustThreshold(); } // Token: 0x06000FAA RID: 4010 RVA: 0x00041530 File Offset: 0x0003F730 private int Find(object key) { if (key == null) { throw new ArgumentNullException("key", "null key"); } Hashtable.Slot[] array = this.table; int[] array2 = this.hashes; uint num = (uint)array.Length; int num2 = this.GetHash(key) & int.MaxValue; uint num3 = (uint)num2; uint num4 = (uint)(((num2 >> 5) + 1) % (int)(num - 1U) + 1); for (uint num5 = num; num5 > 0U; num5 -= 1U) { num3 %= num; Hashtable.Slot slot = array[(int)((UIntPtr)num3)]; int num6 = array2[(int)((UIntPtr)num3)]; object key2 = slot.key; if (key2 == null) { break; } if (key2 == key || ((num6 & 2147483647) == num2 && this.KeyEquals(key, key2))) { return (int)num3; } if ((num6 & -2147483648) == 0) { break; } num3 += num4; } return -1; } // Token: 0x06000FAB RID: 4011 RVA: 0x0004160C File Offset: 0x0003F80C private void Rehash() { int num = this.table.Length; uint num2 = (uint)Hashtable.ToPrime((num << 1) | 1); Hashtable.Slot[] array = new Hashtable.Slot[num2]; Hashtable.Slot[] array2 = this.table; int[] array3 = new int[num2]; int[] array4 = this.hashes; for (int i = 0; i < num; i++) { Hashtable.Slot slot = array2[i]; if (slot.key != null) { int num3 = array4[i] & int.MaxValue; uint num4 = (uint)num3; uint num5 = (uint)(((num3 >> 5) + 1) % (int)(num2 - 1U) + 1); uint num6 = num4 % num2; while (array[(int)((UIntPtr)num6)].key != null) { array3[(int)((UIntPtr)num6)] |= int.MinValue; num4 += num5; num6 = num4 % num2; } array[(int)((UIntPtr)num6)].key = slot.key; array[(int)((UIntPtr)num6)].value = slot.value; array3[(int)((UIntPtr)num6)] |= num3; } } this.modificationCount++; this.SetTable(array, array3); } // Token: 0x06000FAC RID: 4012 RVA: 0x00041738 File Offset: 0x0003F938 private void PutImpl(object key, object value, bool overwrite) { if (key == null) { throw new ArgumentNullException("key", "null key"); } if (this.inUse >= this.threshold) { this.Rehash(); } uint num = (uint)this.table.Length; int num2 = this.GetHash(key) & int.MaxValue; uint num3 = (uint)num2; uint num4 = ((num3 >> 5) + 1U) % (num - 1U) + 1U; Hashtable.Slot[] array = this.table; int[] array2 = this.hashes; int num5 = -1; int num6 = 0; while ((long)num6 < (long)((ulong)num)) { int num7 = (int)(num3 % num); Hashtable.Slot slot = array[num7]; int num8 = array2[num7]; if (num5 == -1 && slot.key == Hashtable.KeyMarker.Removed && (num8 & -2147483648) != 0) { num5 = num7; } if (slot.key == null || (slot.key == Hashtable.KeyMarker.Removed && (num8 & -2147483648) == 0)) { if (num5 == -1) { num5 = num7; } break; } if ((num8 & 2147483647) == num2 && this.KeyEquals(key, slot.key)) { if (overwrite) { array[num7].value = value; this.modificationCount++; return; } throw new ArgumentException("Key duplication when adding: " + key); } else { if (num5 == -1) { array2[num7] |= int.MinValue; } num3 += num4; num6++; } } if (num5 != -1) { array[num5].key = key; array[num5].value = value; array2[num5] |= num2; this.inUse++; this.modificationCount++; } } // Token: 0x06000FAD RID: 4013 RVA: 0x0004190C File Offset: 0x0003FB0C private void CopyToArray(Array arr, int i, Hashtable.EnumeratorMode mode) { IEnumerator enumerator = new Hashtable.Enumerator(this, mode); while (enumerator.MoveNext()) { object obj = enumerator.Current; arr.SetValue(obj, i++); } } // Token: 0x06000FAE RID: 4014 RVA: 0x00041944 File Offset: 0x0003FB44 internal static bool TestPrime(int x) { if ((x & 1) != 0) { int num = (int)Math.Sqrt((double)x); for (int i = 3; i < num; i += 2) { if (x % i == 0) { return false; } } return true; } return x == 2; } // Token: 0x06000FAF RID: 4015 RVA: 0x00041984 File Offset: 0x0003FB84 internal static int CalcPrime(int x) { for (int i = (x & -2) - 1; i < 2147483647; i += 2) { if (Hashtable.TestPrime(i)) { return i; } } return x; } // Token: 0x06000FB0 RID: 4016 RVA: 0x000419BC File Offset: 0x0003FBBC internal static int ToPrime(int x) { for (int i = 0; i < Hashtable.primeTbl.Length; i++) { if (x <= Hashtable.primeTbl[i]) { return Hashtable.primeTbl[i]; } } return Hashtable.CalcPrime(x); } // Token: 0x040003BF RID: 959 private const int CHAIN_MARKER = -2147483648; // Token: 0x040003C0 RID: 960 private int inUse; // Token: 0x040003C1 RID: 961 private int modificationCount; // Token: 0x040003C2 RID: 962 private float loadFactor; // Token: 0x040003C3 RID: 963 private Hashtable.Slot[] table; // Token: 0x040003C4 RID: 964 private int[] hashes; // Token: 0x040003C5 RID: 965 private int threshold; // Token: 0x040003C6 RID: 966 private Hashtable.HashKeys hashKeys; // Token: 0x040003C7 RID: 967 private Hashtable.HashValues hashValues; // Token: 0x040003C8 RID: 968 private IHashCodeProvider hcpRef; // Token: 0x040003C9 RID: 969 private IComparer comparerRef; // Token: 0x040003CA RID: 970 private SerializationInfo serializationInfo; // Token: 0x040003CB RID: 971 private IEqualityComparer equalityComparer; // Token: 0x040003CC RID: 972 private static readonly int[] primeTbl = new int[] { 11, 19, 37, 73, 109, 163, 251, 367, 557, 823, 1237, 1861, 2777, 4177, 6247, 9371, 14057, 21089, 31627, 47431, 71143, 106721, 160073, 240101, 360163, 540217, 810343, 1215497, 1823231, 2734867, 4102283, 6153409, 9230113, 13845163 }; // Token: 0x0200012B RID: 299 [Serializable] internal struct Slot { // Token: 0x040003CD RID: 973 internal object key; // Token: 0x040003CE RID: 974 internal object value; } // Token: 0x0200012C RID: 300 [Serializable] internal class KeyMarker { // Token: 0x040003CF RID: 975 public static readonly Hashtable.KeyMarker Removed = new Hashtable.KeyMarker(); } // Token: 0x0200012D RID: 301 private enum EnumeratorMode { // Token: 0x040003D1 RID: 977 KEY_MODE, // Token: 0x040003D2 RID: 978 VALUE_MODE, // Token: 0x040003D3 RID: 979 ENTRY_MODE } // Token: 0x0200012E RID: 302 [Serializable] private sealed class Enumerator : IEnumerator, IDictionaryEnumerator { // Token: 0x06000FB3 RID: 4019 RVA: 0x00041A10 File Offset: 0x0003FC10 public Enumerator(Hashtable host, Hashtable.EnumeratorMode mode) { this.host = host; this.stamp = host.modificationCount; this.size = host.table.Length; this.mode = mode; this.Reset(); } // Token: 0x06000FB4 RID: 4020 RVA: 0x00041A54 File Offset: 0x0003FC54 public Enumerator(Hashtable host) : this(host, Hashtable.EnumeratorMode.KEY_MODE) { } // Token: 0x06000FB6 RID: 4022 RVA: 0x00041A6C File Offset: 0x0003FC6C private void FailFast() { if (this.host.modificationCount != this.stamp) { throw new InvalidOperationException(Hashtable.Enumerator.xstr); } } // Token: 0x06000FB7 RID: 4023 RVA: 0x00041A90 File Offset: 0x0003FC90 public void Reset() { this.FailFast(); this.pos = -1; this.currentKey = null; this.currentValue = null; } // Token: 0x06000FB8 RID: 4024 RVA: 0x00041AB0 File Offset: 0x0003FCB0 public bool MoveNext() { this.FailFast(); if (this.pos < this.size) { while (++this.pos < this.size) { Hashtable.Slot slot = this.host.table[this.pos]; if (slot.key != null && slot.key != Hashtable.KeyMarker.Removed) { this.currentKey = slot.key; this.currentValue = slot.value; return true; } } } this.currentKey = null; this.currentValue = null; return false; } // Token: 0x1700027B RID: 635 // (get) Token: 0x06000FB9 RID: 4025 RVA: 0x00041B5C File Offset: 0x0003FD5C public DictionaryEntry Entry { get { if (this.currentKey == null) { throw new InvalidOperationException(); } this.FailFast(); return new DictionaryEntry(this.currentKey, this.currentValue); } } // Token: 0x1700027C RID: 636 // (get) Token: 0x06000FBA RID: 4026 RVA: 0x00041B94 File Offset: 0x0003FD94 public object Key { get { if (this.currentKey == null) { throw new InvalidOperationException(); } this.FailFast(); return this.currentKey; } } // Token: 0x1700027D RID: 637 // (get) Token: 0x06000FBB RID: 4027 RVA: 0x00041BB4 File Offset: 0x0003FDB4 public object Value { get { if (this.currentKey == null) { throw new InvalidOperationException(); } this.FailFast(); return this.currentValue; } } // Token: 0x1700027E RID: 638 // (get) Token: 0x06000FBC RID: 4028 RVA: 0x00041BD4 File Offset: 0x0003FDD4 public object Current { get { if (this.currentKey == null) { throw new InvalidOperationException(); } switch (this.mode) { case Hashtable.EnumeratorMode.KEY_MODE: return this.currentKey; case Hashtable.EnumeratorMode.VALUE_MODE: return this.currentValue; case Hashtable.EnumeratorMode.ENTRY_MODE: return new DictionaryEntry(this.currentKey, this.currentValue); default: throw new Exception("should never happen"); } } } // Token: 0x040003D4 RID: 980 private Hashtable host; // Token: 0x040003D5 RID: 981 private int stamp; // Token: 0x040003D6 RID: 982 private int pos; // Token: 0x040003D7 RID: 983 private int size; // Token: 0x040003D8 RID: 984 private Hashtable.EnumeratorMode mode; // Token: 0x040003D9 RID: 985 private object currentKey; // Token: 0x040003DA RID: 986 private object currentValue; // Token: 0x040003DB RID: 987 private static readonly string xstr = "Hashtable.Enumerator: snapshot out of sync."; } // Token: 0x0200012F RID: 303 [DebuggerTypeProxy(typeof(CollectionDebuggerView))] [DebuggerDisplay("Count={Count}")] [Serializable] private class HashKeys : IEnumerable, ICollection { // Token: 0x06000FBD RID: 4029 RVA: 0x00041C40 File Offset: 0x0003FE40 public HashKeys(Hashtable host) { if (host == null) { throw new ArgumentNullException(); } this.host = host; } // Token: 0x1700027F RID: 639 // (get) Token: 0x06000FBE RID: 4030 RVA: 0x00041C5C File Offset: 0x0003FE5C public virtual int Count { get { return this.host.Count; } } // Token: 0x17000280 RID: 640 // (get) Token: 0x06000FBF RID: 4031 RVA: 0x00041C6C File Offset: 0x0003FE6C public virtual bool IsSynchronized { get { return this.host.IsSynchronized; } } // Token: 0x17000281 RID: 641 // (get) Token: 0x06000FC0 RID: 4032 RVA: 0x00041C7C File Offset: 0x0003FE7C public virtual object SyncRoot { get { return this.host.SyncRoot; } } // Token: 0x06000FC1 RID: 4033 RVA: 0x00041C8C File Offset: 0x0003FE8C public virtual void CopyTo(Array array, int arrayIndex) { if (array == null) { throw new ArgumentNullException("array"); } if (array.Rank != 1) { throw new ArgumentException("array"); } if (arrayIndex < 0) { throw new ArgumentOutOfRangeException("arrayIndex"); } if (array.Length - arrayIndex < this.Count) { throw new ArgumentException("not enough space"); } this.host.CopyToArray(array, arrayIndex, Hashtable.EnumeratorMode.KEY_MODE); } // Token: 0x06000FC2 RID: 4034 RVA: 0x00041D00 File Offset: 0x0003FF00 public virtual IEnumerator GetEnumerator() { return new Hashtable.Enumerator(this.host, Hashtable.EnumeratorMode.KEY_MODE); } // Token: 0x040003DC RID: 988 private Hashtable host; } // Token: 0x02000130 RID: 304 [DebuggerTypeProxy(typeof(CollectionDebuggerView))] [DebuggerDisplay("Count={Count}")] [Serializable] private class HashValues : IEnumerable, ICollection { // Token: 0x06000FC3 RID: 4035 RVA: 0x00041D10 File Offset: 0x0003FF10 public HashValues(Hashtable host) { if (host == null) { throw new ArgumentNullException(); } this.host = host; } // Token: 0x17000282 RID: 642 // (get) Token: 0x06000FC4 RID: 4036 RVA: 0x00041D2C File Offset: 0x0003FF2C public virtual int Count { get { return this.host.Count; } } // Token: 0x17000283 RID: 643 // (get) Token: 0x06000FC5 RID: 4037 RVA: 0x00041D3C File Offset: 0x0003FF3C public virtual bool IsSynchronized { get { return this.host.IsSynchronized; } } // Token: 0x17000284 RID: 644 // (get) Token: 0x06000FC6 RID: 4038 RVA: 0x00041D4C File Offset: 0x0003FF4C public virtual object SyncRoot { get { return this.host.SyncRoot; } } // Token: 0x06000FC7 RID: 4039 RVA: 0x00041D5C File Offset: 0x0003FF5C public virtual void CopyTo(Array array, int arrayIndex) { if (array == null) { throw new ArgumentNullException("array"); } if (array.Rank != 1) { throw new ArgumentException("array"); } if (arrayIndex < 0) { throw new ArgumentOutOfRangeException("arrayIndex"); } if (array.Length - arrayIndex < this.Count) { throw new ArgumentException("not enough space"); } this.host.CopyToArray(array, arrayIndex, Hashtable.EnumeratorMode.VALUE_MODE); } // Token: 0x06000FC8 RID: 4040 RVA: 0x00041DD0 File Offset: 0x0003FFD0 public virtual IEnumerator GetEnumerator() { return new Hashtable.Enumerator(this.host, Hashtable.EnumeratorMode.VALUE_MODE); } // Token: 0x040003DD RID: 989 private Hashtable host; } // Token: 0x02000131 RID: 305 [Serializable] private class SyncHashtable : Hashtable, IEnumerable { // Token: 0x06000FC9 RID: 4041 RVA: 0x00041DE0 File Offset: 0x0003FFE0 public SyncHashtable(Hashtable host) { if (host == null) { throw new ArgumentNullException(); } this.host = host; } // Token: 0x06000FCA RID: 4042 RVA: 0x00041DFC File Offset: 0x0003FFFC internal SyncHashtable(SerializationInfo info, StreamingContext context) { this.host = (Hashtable)info.GetValue("ParentTable", typeof(Hashtable)); } // Token: 0x06000FCB RID: 4043 RVA: 0x00041E30 File Offset: 0x00040030 IEnumerator IEnumerable.GetEnumerator() { return new Hashtable.Enumerator(this.host, Hashtable.EnumeratorMode.ENTRY_MODE); } // Token: 0x06000FCC RID: 4044 RVA: 0x00041E40 File Offset: 0x00040040 public override void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("ParentTable", this.host); } // Token: 0x17000285 RID: 645 // (get) Token: 0x06000FCD RID: 4045 RVA: 0x00041E54 File Offset: 0x00040054 public override int Count { get { return this.host.Count; } } // Token: 0x17000286 RID: 646 // (get) Token: 0x06000FCE RID: 4046 RVA: 0x00041E64 File Offset: 0x00040064 public override bool IsSynchronized { get { return true; } } // Token: 0x17000287 RID: 647 // (get) Token: 0x06000FCF RID: 4047 RVA: 0x00041E68 File Offset: 0x00040068 public override object SyncRoot { get { return this.host.SyncRoot; } } // Token: 0x17000288 RID: 648 // (get) Token: 0x06000FD0 RID: 4048 RVA: 0x00041E78 File Offset: 0x00040078 public override bool IsFixedSize { get { return this.host.IsFixedSize; } } // Token: 0x17000289 RID: 649 // (get) Token: 0x06000FD1 RID: 4049 RVA: 0x00041E88 File Offset: 0x00040088 public override bool IsReadOnly { get { return this.host.IsReadOnly; } } // Token: 0x1700028A RID: 650 // (get) Token: 0x06000FD2 RID: 4050 RVA: 0x00041E98 File Offset: 0x00040098 public override ICollection Keys { get { ICollection collection = null; object syncRoot = this.host.SyncRoot; lock (syncRoot) { collection = this.host.Keys; } return collection; } } // Token: 0x1700028B RID: 651 // (get) Token: 0x06000FD3 RID: 4051 RVA: 0x00041EF0 File Offset: 0x000400F0 public override ICollection Values { get { ICollection collection = null; object syncRoot = this.host.SyncRoot; lock (syncRoot) { collection = this.host.Values; } return collection; } } // Token: 0x1700028C RID: 652 public override object this[object key] { get { return this.host[key]; } set { object syncRoot = this.host.SyncRoot; lock (syncRoot) { this.host[key] = value; } } } // Token: 0x06000FD6 RID: 4054 RVA: 0x00041FAC File Offset: 0x000401AC public override void CopyTo(Array array, int arrayIndex) { this.host.CopyTo(array, arrayIndex); } // Token: 0x06000FD7 RID: 4055 RVA: 0x00041FBC File Offset: 0x000401BC public override void Add(object key, object value) { object syncRoot = this.host.SyncRoot; lock (syncRoot) { this.host.Add(key, value); } } // Token: 0x06000FD8 RID: 4056 RVA: 0x00042010 File Offset: 0x00040210 public override void Clear() { object syncRoot = this.host.SyncRoot; lock (syncRoot) { this.host.Clear(); } } // Token: 0x06000FD9 RID: 4057 RVA: 0x00042064 File Offset: 0x00040264 public override bool Contains(object key) { return this.host.Find(key) >= 0; } // Token: 0x06000FDA RID: 4058 RVA: 0x00042078 File Offset: 0x00040278 public override IDictionaryEnumerator GetEnumerator() { return new Hashtable.Enumerator(this.host, Hashtable.EnumeratorMode.ENTRY_MODE); } // Token: 0x06000FDB RID: 4059 RVA: 0x00042088 File Offset: 0x00040288 public override void Remove(object key) { object syncRoot = this.host.SyncRoot; lock (syncRoot) { this.host.Remove(key); } } // Token: 0x06000FDC RID: 4060 RVA: 0x000420DC File Offset: 0x000402DC public override bool ContainsKey(object key) { return this.host.Contains(key); } // Token: 0x06000FDD RID: 4061 RVA: 0x000420EC File Offset: 0x000402EC public override bool ContainsValue(object value) { return this.host.ContainsValue(value); } // Token: 0x06000FDE RID: 4062 RVA: 0x000420FC File Offset: 0x000402FC public override object Clone() { object syncRoot = this.host.SyncRoot; object obj; lock (syncRoot) { obj = new Hashtable.SyncHashtable((Hashtable)this.host.Clone()); } return obj; } // Token: 0x040003DE RID: 990 private Hashtable host; } } }