ConfigurationElementCollection
public abstract class ConfigurationElementCollection : ConfigurationElement, ICollection, IEnumerable
using System.Collections;
using System.Diagnostics;
using System.Xml;
namespace System.Configuration
{
[DebuggerDisplay("Count = {Count}")]
public abstract class ConfigurationElementCollection : ConfigurationElement, ICollection, IEnumerable
{
private enum InheritedType
{
InNeither,
InParent,
InSelf,
InBothSame,
InBothDiff,
InBothCopyNoRemove
}
private enum EntryType
{
Inherited,
Replaced,
Removed,
Added
}
private sealed class Entry
{
private readonly object _key;
internal EntryType EntryType;
internal ConfigurationElement Value;
internal Entry(EntryType type, object key, ConfigurationElement value)
{
EntryType = type;
_key = key;
Value = value;
}
internal object GetKey(ConfigurationElementCollection thisCollection)
{
if (Value == null)
return _key;
return thisCollection.GetElementKeyInternal(Value);
}
}
private sealed class Enumerator : IDictionaryEnumerator, IEnumerator
{
private readonly IEnumerator _itemsEnumerator;
private readonly ConfigurationElementCollection _thisCollection;
private DictionaryEntry _current;
object IEnumerator.Current {
get {
return _current.Value;
}
}
DictionaryEntry IDictionaryEnumerator.Entry {
get {
return _current;
}
}
object IDictionaryEnumerator.Key {
get {
return _current.Key;
}
}
object IDictionaryEnumerator.Value {
get {
return _current.Value;
}
}
internal Enumerator(ArrayList items, ConfigurationElementCollection collection)
{
_itemsEnumerator = items.GetEnumerator();
_thisCollection = collection;
}
bool IEnumerator.MoveNext()
{
while (_itemsEnumerator.MoveNext()) {
Entry entry = (Entry)_itemsEnumerator.Current;
if (entry.EntryType != EntryType.Removed) {
_current.Key = (entry.GetKey(_thisCollection) ?? "key");
_current.Value = entry.Value;
return true;
}
}
return false;
}
void IEnumerator.Reset()
{
_itemsEnumerator.Reset();
}
}
internal const string DefaultAddItemName = "add";
internal const string DefaultRemoveItemName = "remove";
internal const string DefaultClearItemsName = "clear";
private readonly IComparer _comparer;
private string _addElement = "add";
private string _clearElement = "clear";
private bool _collectionCleared;
private bool _emitClearTag;
private int _inheritedCount;
private bool _modified;
private bool _readOnly;
private int _removedItemCount;
private string _removeElement = "remove";
internal bool InternalAddToEnd;
internal string InternalElementTagName = string.Empty;
private ArrayList Items { get; } = new ArrayList();
protected internal string AddElementName {
get {
return _addElement;
}
set {
_addElement = value;
if (BaseConfigurationRecord.IsReservedAttributeName(value))
throw new ArgumentException(System.SR.Format(System.SR.Item_name_reserved, "add", value));
}
}
protected internal string RemoveElementName {
get {
return _removeElement;
}
set {
if (BaseConfigurationRecord.IsReservedAttributeName(value))
throw new ArgumentException(System.SR.Format(System.SR.Item_name_reserved, "remove", value));
_removeElement = value;
}
}
protected internal string ClearElementName {
get {
return _clearElement;
}
set {
if (BaseConfigurationRecord.IsReservedAttributeName(value))
throw new ArgumentException(System.SR.Format(System.SR.Item_name_reserved, "clear", value));
_clearElement = value;
}
}
public bool EmitClear {
get {
return _emitClearTag;
}
set {
if (IsReadOnly())
throw new ConfigurationErrorsException(System.SR.Config_base_read_only);
if (value) {
CheckLockedElement(_clearElement, null);
CheckLockedElement(_removeElement, null);
}
_modified = true;
_emitClearTag = value;
}
}
protected virtual string ElementName => "";
internal string LockableElements {
get {
if (CollectionType == ConfigurationElementCollectionType.AddRemoveClearMap || CollectionType == ConfigurationElementCollectionType.AddRemoveClearMapAlternate) {
string text = "'" + AddElementName + "'";
if (RemoveElementName.Length != 0)
text = text + ", '" + RemoveElementName + "'";
if (ClearElementName.Length != 0)
text = text + ", '" + ClearElementName + "'";
return text;
}
if (!string.IsNullOrEmpty(ElementName))
return "'" + ElementName + "'";
return string.Empty;
}
}
protected virtual bool ThrowOnDuplicate {
get {
if (CollectionType != ConfigurationElementCollectionType.AddRemoveClearMap)
return CollectionType == ConfigurationElementCollectionType.AddRemoveClearMapAlternate;
return true;
}
}
public virtual ConfigurationElementCollectionType CollectionType => ConfigurationElementCollectionType.AddRemoveClearMap;
public int Count => Items.Count - _removedItemCount;
public bool IsSynchronized => false;
public object SyncRoot => null;
protected ConfigurationElementCollection()
{
}
protected ConfigurationElementCollection(IComparer comparer)
{
if (comparer == null)
throw new ArgumentNullException("comparer");
_comparer = comparer;
}
void ICollection.CopyTo(Array arr, int index)
{
foreach (Entry item in Items) {
if (item.EntryType != EntryType.Removed)
arr.SetValue(item.Value, index++);
}
}
public IEnumerator GetEnumerator()
{
return GetEnumeratorImpl();
}
internal override void AssociateContext(BaseConfigurationRecord configRecord)
{
base.AssociateContext(configRecord);
foreach (Entry item in Items) {
item.Value?.AssociateContext(configRecord);
}
}
protected internal override bool IsModified()
{
if (_modified)
return true;
if (base.IsModified())
return true;
foreach (Entry item in Items) {
if (item.EntryType != EntryType.Removed) {
ConfigurationElement value = item.Value;
if (value.IsModified())
return true;
}
}
return false;
}
protected internal override void ResetModified()
{
_modified = false;
base.ResetModified();
foreach (Entry item in Items) {
if (item.EntryType != EntryType.Removed) {
ConfigurationElement value = item.Value;
value.ResetModified();
}
}
}
public override bool IsReadOnly()
{
return _readOnly;
}
protected internal override void SetReadOnly()
{
_readOnly = true;
foreach (Entry item in Items) {
if (item.EntryType != EntryType.Removed) {
ConfigurationElement value = item.Value;
value.SetReadOnly();
}
}
}
internal virtual IEnumerator GetEnumeratorImpl()
{
return new Enumerator(Items, this);
}
internal IEnumerator GetElementsEnumerator()
{
return new Enumerator(Items, this);
}
public override bool Equals(object compareTo)
{
if (compareTo == null || compareTo.GetType() != GetType())
return false;
ConfigurationElementCollection configurationElementCollection = (ConfigurationElementCollection)compareTo;
if (Count != configurationElementCollection.Count)
return false;
foreach (Entry item in Items) {
bool flag = false;
foreach (Entry item2 in configurationElementCollection.Items) {
if (object.Equals(item.Value, item2.Value)) {
flag = true;
break;
}
}
if (!flag)
return false;
}
return true;
}
public override int GetHashCode()
{
int num = 0;
foreach (Entry item in Items) {
ConfigurationElement value = item.Value;
num ^= value.GetHashCode();
}
return num;
}
protected internal override void Unmerge(ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode)
{
base.Unmerge(sourceElement, parentElement, saveMode);
if (sourceElement != null) {
ConfigurationElementCollection configurationElementCollection = parentElement as ConfigurationElementCollection;
ConfigurationElementCollection configurationElementCollection2 = sourceElement as ConfigurationElementCollection;
Hashtable hashtable = new Hashtable();
_lockedAllExceptAttributesList = sourceElement._lockedAllExceptAttributesList;
_lockedAllExceptElementsList = sourceElement._lockedAllExceptElementsList;
_itemLockedFlag = sourceElement._itemLockedFlag;
_lockedAttributesList = sourceElement._lockedAttributesList;
_lockedElementsList = sourceElement._lockedElementsList;
AssociateContext(sourceElement._configRecord);
if (parentElement != null) {
if (parentElement._lockedAttributesList != null)
_lockedAttributesList = UnMergeLockList(sourceElement._lockedAttributesList, parentElement._lockedAttributesList, saveMode);
if (parentElement._lockedElementsList != null)
_lockedElementsList = UnMergeLockList(sourceElement._lockedElementsList, parentElement._lockedElementsList, saveMode);
if (parentElement._lockedAllExceptAttributesList != null)
_lockedAllExceptAttributesList = UnMergeLockList(sourceElement._lockedAllExceptAttributesList, parentElement._lockedAllExceptAttributesList, saveMode);
if (parentElement._lockedAllExceptElementsList != null)
_lockedAllExceptElementsList = UnMergeLockList(sourceElement._lockedAllExceptElementsList, parentElement._lockedAllExceptElementsList, saveMode);
}
if (CollectionType == ConfigurationElementCollectionType.AddRemoveClearMap || CollectionType == ConfigurationElementCollectionType.AddRemoveClearMapAlternate) {
_collectionCleared = configurationElementCollection2._collectionCleared;
EmitClear = ((saveMode == ConfigurationSaveMode.Full && _clearElement.Length != 0) || (saveMode == ConfigurationSaveMode.Modified && _collectionCleared) || configurationElementCollection2.EmitClear);
if (configurationElementCollection != null && !EmitClear) {
foreach (Entry item in configurationElementCollection.Items) {
if (item.EntryType != EntryType.Removed)
hashtable[item.GetKey(this)] = InheritedType.InParent;
}
}
foreach (Entry item2 in configurationElementCollection2.Items) {
if (item2.EntryType != EntryType.Removed) {
if (hashtable.Contains(item2.GetKey(this))) {
Entry entry3 = (Entry)configurationElementCollection.Items[configurationElementCollection.RealIndexOf(item2.Value)];
ConfigurationElement value = item2.Value;
if (value.Equals(entry3.Value)) {
hashtable[item2.GetKey(this)] = InheritedType.InBothSame;
if (saveMode == ConfigurationSaveMode.Modified) {
if (value.IsModified())
hashtable[item2.GetKey(this)] = InheritedType.InBothDiff;
else if (value.ElementPresent) {
hashtable[item2.GetKey(this)] = InheritedType.InBothCopyNoRemove;
}
}
} else {
hashtable[item2.GetKey(this)] = InheritedType.InBothDiff;
if (CollectionType == ConfigurationElementCollectionType.AddRemoveClearMapAlternate && item2.EntryType == EntryType.Added)
hashtable[item2.GetKey(this)] = InheritedType.InBothCopyNoRemove;
}
} else
hashtable[item2.GetKey(this)] = InheritedType.InSelf;
}
}
if (configurationElementCollection != null && !EmitClear) {
foreach (Entry item3 in configurationElementCollection.Items) {
if (item3.EntryType != EntryType.Removed) {
InheritedType inheritedType = (InheritedType)hashtable[item3.GetKey(this)];
if (inheritedType == InheritedType.InParent || inheritedType == InheritedType.InBothDiff) {
ConfigurationElement configurationElement = CallCreateNewElement(item3.GetKey(this).ToString());
configurationElement.Reset(item3.Value);
BaseAdd(configurationElement, ThrowOnDuplicate, true);
BaseRemove(item3.GetKey(this), false);
}
}
}
}
foreach (Entry item4 in configurationElementCollection2.Items) {
if (item4.EntryType != EntryType.Removed) {
InheritedType inheritedType2 = (InheritedType)hashtable[item4.GetKey(this)];
if (inheritedType2 == InheritedType.InSelf || inheritedType2 == InheritedType.InBothDiff || inheritedType2 == InheritedType.InBothCopyNoRemove) {
ConfigurationElement configurationElement2 = CallCreateNewElement(item4.GetKey(this).ToString());
configurationElement2.Unmerge(item4.Value, null, saveMode);
if (inheritedType2 == InheritedType.InSelf)
configurationElement2.RemoveAllInheritedLocks();
BaseAdd(configurationElement2, ThrowOnDuplicate, true);
}
}
}
} else if (CollectionType == ConfigurationElementCollectionType.BasicMap || CollectionType == ConfigurationElementCollectionType.BasicMapAlternate) {
foreach (Entry item5 in configurationElementCollection2.Items) {
bool flag = false;
Entry entry7 = null;
if (item5.EntryType == EntryType.Added || item5.EntryType == EntryType.Replaced) {
bool flag2 = false;
if (configurationElementCollection != null) {
foreach (Entry item6 in configurationElementCollection.Items) {
if (object.Equals(item5.GetKey(this), item6.GetKey(this)) && !IsElementName(item5.GetKey(this).ToString())) {
flag = true;
entry7 = item6;
}
if (object.Equals(item5.Value, item6.Value)) {
flag = true;
flag2 = true;
entry7 = item6;
break;
}
}
}
ConfigurationElement configurationElement3 = CallCreateNewElement(item5.GetKey(this).ToString());
if (!flag) {
configurationElement3.Unmerge(item5.Value, null, saveMode);
BaseAdd(-1, configurationElement3, true);
} else {
ConfigurationElement value2 = item5.Value;
if (!flag2 || (saveMode == ConfigurationSaveMode.Modified && value2.IsModified()) || saveMode == ConfigurationSaveMode.Full) {
configurationElement3.Unmerge(item5.Value, entry7.Value, saveMode);
BaseAdd(-1, configurationElement3, true);
}
}
}
}
}
}
}
protected internal override void Reset(ConfigurationElement parentElement)
{
ConfigurationElementCollection configurationElementCollection = parentElement as ConfigurationElementCollection;
ResetLockLists(parentElement);
if (configurationElementCollection != null) {
foreach (Entry item in configurationElementCollection.Items) {
ConfigurationElement configurationElement = CallCreateNewElement(item.GetKey(this).ToString());
configurationElement.Reset(item.Value);
if ((CollectionType == ConfigurationElementCollectionType.AddRemoveClearMap || CollectionType == ConfigurationElementCollectionType.AddRemoveClearMapAlternate) && (item.EntryType == EntryType.Added || item.EntryType == EntryType.Replaced))
BaseAdd(configurationElement, true, true);
else if (CollectionType == ConfigurationElementCollectionType.BasicMap || CollectionType == ConfigurationElementCollectionType.BasicMapAlternate) {
BaseAdd(-1, configurationElement, true);
}
}
_inheritedCount = Count;
}
}
public void CopyTo(ConfigurationElement[] array, int index)
{
((ICollection)this).CopyTo((Array)array, index);
}
protected virtual void BaseAdd(ConfigurationElement element)
{
BaseAdd(element, ThrowOnDuplicate);
}
protected internal void BaseAdd(ConfigurationElement element, bool throwIfExists)
{
BaseAdd(element, throwIfExists, false);
}
private void BaseAdd(ConfigurationElement element, bool throwIfExists, bool ignoreLocks)
{
bool flagAsReplaced = false;
bool flag = InternalAddToEnd;
if (IsReadOnly())
throw new ConfigurationErrorsException(System.SR.Config_base_read_only);
if (base.LockItem && !ignoreLocks)
throw new ConfigurationErrorsException(System.SR.Format(System.SR.Config_base_element_locked, _addElement));
object elementKeyInternal = GetElementKeyInternal(element);
int num = -1;
for (int i = 0; i < Items.Count; i++) {
Entry entry = (Entry)Items[i];
if (CompareKeys(elementKeyInternal, entry.GetKey(this))) {
if (entry.Value != null && entry.Value.LockItem && !ignoreLocks)
throw new ConfigurationErrorsException(System.SR.Config_base_collection_item_locked);
if ((entry.EntryType != EntryType.Removed) & throwIfExists) {
if (!element.Equals(entry.Value))
throw new ConfigurationErrorsException(System.SR.Format(System.SR.Config_base_collection_entry_already_exists, elementKeyInternal), element.PropertyFileName(""), element.PropertyLineNumber(""));
entry.Value = element;
} else {
if (entry.EntryType != EntryType.Added) {
if ((CollectionType == ConfigurationElementCollectionType.AddRemoveClearMap || CollectionType == ConfigurationElementCollectionType.AddRemoveClearMapAlternate) && entry.EntryType == EntryType.Removed && _removedItemCount > 0)
_removedItemCount--;
entry.EntryType = EntryType.Replaced;
flagAsReplaced = true;
}
if (flag || CollectionType == ConfigurationElementCollectionType.AddRemoveClearMapAlternate) {
num = i;
if (entry.EntryType == EntryType.Added)
flag = true;
break;
}
if (!ignoreLocks) {
element.HandleLockedAttributes(entry.Value);
element.MergeLocks(entry.Value);
}
entry.Value = element;
_modified = true;
}
return;
}
}
if (num >= 0) {
Items.RemoveAt(num);
if (CollectionType == ConfigurationElementCollectionType.AddRemoveClearMapAlternate && num > Count + _removedItemCount - _inheritedCount)
_inheritedCount--;
}
BaseAddInternal(flag ? (-1) : num, element, flagAsReplaced, ignoreLocks);
_modified = true;
}
protected int BaseIndexOf(ConfigurationElement element)
{
int num = 0;
object elementKeyInternal = GetElementKeyInternal(element);
foreach (Entry item in Items) {
if (item.EntryType != EntryType.Removed) {
if (CompareKeys(elementKeyInternal, item.GetKey(this)))
return num;
num++;
}
}
return -1;
}
internal int RealIndexOf(ConfigurationElement element)
{
int num = 0;
object elementKeyInternal = GetElementKeyInternal(element);
foreach (Entry item in Items) {
if (CompareKeys(elementKeyInternal, item.GetKey(this)))
return num;
num++;
}
return -1;
}
private void BaseAddInternal(int index, ConfigurationElement element, bool flagAsReplaced, bool ignoreLocks)
{
element.AssociateContext(_configRecord);
element.CallInit();
if (IsReadOnly())
throw new ConfigurationErrorsException(System.SR.Config_base_read_only);
if (!ignoreLocks) {
if (CollectionType == ConfigurationElementCollectionType.BasicMap || CollectionType == ConfigurationElementCollectionType.BasicMapAlternate) {
if (BaseConfigurationRecord.IsReservedAttributeName(ElementName))
throw new ArgumentException(System.SR.Format(System.SR.Basicmap_item_name_reserved, ElementName));
CheckLockedElement(ElementName, null);
}
if (CollectionType == ConfigurationElementCollectionType.AddRemoveClearMap || CollectionType == ConfigurationElementCollectionType.AddRemoveClearMapAlternate)
CheckLockedElement(_addElement, null);
}
if (CollectionType == ConfigurationElementCollectionType.BasicMapAlternate || CollectionType == ConfigurationElementCollectionType.AddRemoveClearMapAlternate) {
if (index == -1)
index = Count + _removedItemCount - _inheritedCount;
else if (index > Count + _removedItemCount - _inheritedCount && !flagAsReplaced) {
throw new ConfigurationErrorsException(System.SR.Config_base_cannot_add_items_below_inherited_items);
}
}
if (CollectionType == ConfigurationElementCollectionType.BasicMap && index >= 0 && index < _inheritedCount)
throw new ConfigurationErrorsException(System.SR.Config_base_cannot_add_items_above_inherited_items);
EntryType type = flagAsReplaced ? EntryType.Replaced : EntryType.Added;
object elementKeyInternal = GetElementKeyInternal(element);
if (index >= 0) {
if (index > Items.Count)
throw new ConfigurationErrorsException(System.SR.Format(System.SR.IndexOutOfRange, index));
Items.Insert(index, new Entry(type, elementKeyInternal, element));
} else
Items.Add(new Entry(type, elementKeyInternal, element));
_modified = true;
}
protected virtual void BaseAdd(int index, ConfigurationElement element)
{
BaseAdd(index, element, false);
}
private void BaseAdd(int index, ConfigurationElement element, bool ignoreLocks)
{
if (IsReadOnly())
throw new ConfigurationErrorsException(System.SR.Config_base_read_only);
if (index < -1)
throw new ConfigurationErrorsException(System.SR.Format(System.SR.IndexOutOfRange, index));
if (index != -1 && (CollectionType == ConfigurationElementCollectionType.AddRemoveClearMap || CollectionType == ConfigurationElementCollectionType.AddRemoveClearMapAlternate)) {
int num = 0;
if (index > 0) {
foreach (Entry item in Items) {
if (item.EntryType != EntryType.Removed)
index--;
if (index == 0)
break;
num++;
}
index = ++num;
}
object elementKeyInternal = GetElementKeyInternal(element);
foreach (Entry item2 in Items) {
if (CompareKeys(elementKeyInternal, item2.GetKey(this)) && item2.EntryType != EntryType.Removed) {
if (!element.Equals(item2.Value))
throw new ConfigurationErrorsException(System.SR.Format(System.SR.Config_base_collection_entry_already_exists, elementKeyInternal), element.PropertyFileName(""), element.PropertyLineNumber(""));
return;
}
}
}
BaseAddInternal(index, element, false, ignoreLocks);
}
protected internal void BaseRemove(object key)
{
BaseRemove(key, false);
}
private void BaseRemove(object key, bool throwIfMissing)
{
if (IsReadOnly())
throw new ConfigurationErrorsException(System.SR.Config_base_read_only);
int num = 0;
foreach (Entry item in Items) {
if (CompareKeys(key, item.GetKey(this))) {
if (item.Value == null) {
if (throwIfMissing)
throw new ConfigurationErrorsException(System.SR.Format(System.SR.Config_base_collection_entry_not_found, key));
} else {
if (item.Value.LockItem)
throw new ConfigurationErrorsException(System.SR.Format(System.SR.Config_base_attribute_locked, key));
if (!item.Value.ElementPresent)
CheckLockedElement(_removeElement, null);
switch (item.EntryType) {
case EntryType.Added:
if (CollectionType != ConfigurationElementCollectionType.AddRemoveClearMap && CollectionType != ConfigurationElementCollectionType.AddRemoveClearMapAlternate) {
if (CollectionType == ConfigurationElementCollectionType.BasicMapAlternate && num >= Count - _inheritedCount)
throw new ConfigurationErrorsException(System.SR.Config_base_cannot_remove_inherited_items);
if (CollectionType == ConfigurationElementCollectionType.BasicMap && num < _inheritedCount)
throw new ConfigurationErrorsException(System.SR.Config_base_cannot_remove_inherited_items);
Items.RemoveAt(num);
} else {
item.EntryType = EntryType.Removed;
_removedItemCount++;
}
break;
case EntryType.Removed:
if (throwIfMissing)
throw new ConfigurationErrorsException(System.SR.Config_base_collection_entry_already_removed);
break;
default:
if (CollectionType != ConfigurationElementCollectionType.AddRemoveClearMap && CollectionType != ConfigurationElementCollectionType.AddRemoveClearMapAlternate)
throw new ConfigurationErrorsException(System.SR.Config_base_collection_elements_may_not_be_removed);
item.EntryType = EntryType.Removed;
_removedItemCount++;
break;
}
_modified = true;
}
return;
}
num++;
}
if (throwIfMissing)
throw new ConfigurationErrorsException(System.SR.Format(System.SR.Config_base_collection_entry_not_found, key));
if (CollectionType == ConfigurationElementCollectionType.AddRemoveClearMap || CollectionType == ConfigurationElementCollectionType.AddRemoveClearMapAlternate) {
if (CollectionType == ConfigurationElementCollectionType.AddRemoveClearMapAlternate)
Items.Insert(Count + _removedItemCount - _inheritedCount, new Entry(EntryType.Removed, key, null));
else
Items.Add(new Entry(EntryType.Removed, key, null));
_removedItemCount++;
}
}
protected internal ConfigurationElement BaseGet(object key)
{
foreach (Entry item in Items) {
if (item.EntryType != EntryType.Removed && CompareKeys(key, item.GetKey(this)))
return item.Value;
}
return null;
}
protected internal bool BaseIsRemoved(object key)
{
foreach (Entry item in Items) {
if (CompareKeys(key, item.GetKey(this)))
return item.EntryType == EntryType.Removed;
}
return false;
}
protected internal ConfigurationElement BaseGet(int index)
{
if (index < 0)
throw new ConfigurationErrorsException(System.SR.Format(System.SR.IndexOutOfRange, index));
int num = 0;
Entry entry = null;
foreach (Entry item in Items) {
if (num == index && item.EntryType != EntryType.Removed) {
entry = item;
break;
}
if (item.EntryType != EntryType.Removed)
num++;
}
if (entry != null)
return entry.Value;
throw new ConfigurationErrorsException(System.SR.Format(System.SR.IndexOutOfRange, index));
}
protected internal object[] BaseGetAllKeys()
{
object[] array = new object[Count];
int num = 0;
foreach (Entry item in Items) {
if (item.EntryType != EntryType.Removed) {
array[num] = item.GetKey(this);
num++;
}
}
return array;
}
protected internal object BaseGetKey(int index)
{
int num = 0;
Entry entry = null;
if (index < 0)
throw new ConfigurationErrorsException(System.SR.Format(System.SR.IndexOutOfRange, index));
foreach (Entry item in Items) {
if (num == index && item.EntryType != EntryType.Removed) {
entry = item;
break;
}
if (item.EntryType != EntryType.Removed)
num++;
}
if (entry == null)
throw new ConfigurationErrorsException(System.SR.Format(System.SR.IndexOutOfRange, index));
return entry.GetKey(this);
}
protected internal void BaseClear()
{
if (IsReadOnly())
throw new ConfigurationErrorsException(System.SR.Config_base_read_only);
CheckLockedElement(_clearElement, null);
CheckLockedElement(_removeElement, null);
_modified = true;
_collectionCleared = true;
if ((CollectionType == ConfigurationElementCollectionType.BasicMap || CollectionType == ConfigurationElementCollectionType.BasicMapAlternate) && _inheritedCount > 0) {
int index = 0;
if (CollectionType == ConfigurationElementCollectionType.BasicMapAlternate)
index = 0;
if (CollectionType == ConfigurationElementCollectionType.BasicMap)
index = _inheritedCount;
while (Count - _inheritedCount > 0) {
Items.RemoveAt(index);
}
} else {
int num = 0;
int num2 = 0;
int count = Count;
for (int i = 0; i < Items.Count; i++) {
Entry entry = (Entry)Items[i];
if (entry.Value != null && entry.Value.LockItem)
throw new ConfigurationErrorsException(System.SR.Config_base_collection_item_locked_cannot_clear);
}
for (int num3 = Items.Count - 1; num3 >= 0; num3--) {
Entry entry2 = (Entry)Items[num3];
if ((CollectionType == ConfigurationElementCollectionType.AddRemoveClearMap && num3 < _inheritedCount) || (CollectionType == ConfigurationElementCollectionType.AddRemoveClearMapAlternate && num3 >= count - _inheritedCount))
num++;
if (entry2.EntryType == EntryType.Removed)
num2++;
Items.RemoveAt(num3);
}
_inheritedCount -= num;
_removedItemCount -= num2;
}
}
protected internal void BaseRemoveAt(int index)
{
if (IsReadOnly())
throw new ConfigurationErrorsException(System.SR.Config_base_read_only);
int num = 0;
Entry entry = null;
foreach (Entry item in Items) {
if (num == index && item.EntryType != EntryType.Removed) {
entry = item;
break;
}
if (item.EntryType != EntryType.Removed)
num++;
}
if (entry == null)
throw new ConfigurationErrorsException(System.SR.Format(System.SR.IndexOutOfRange, index));
if (entry.Value.LockItem)
throw new ConfigurationErrorsException(System.SR.Format(System.SR.Config_base_attribute_locked, entry.GetKey(this)));
if (!entry.Value.ElementPresent)
CheckLockedElement(_removeElement, null);
switch (entry.EntryType) {
case EntryType.Added:
if (CollectionType != ConfigurationElementCollectionType.AddRemoveClearMap && CollectionType != ConfigurationElementCollectionType.AddRemoveClearMapAlternate) {
if (CollectionType == ConfigurationElementCollectionType.BasicMapAlternate && index >= Count - _inheritedCount)
throw new ConfigurationErrorsException(System.SR.Config_base_cannot_remove_inherited_items);
if (CollectionType == ConfigurationElementCollectionType.BasicMap && index < _inheritedCount)
throw new ConfigurationErrorsException(System.SR.Config_base_cannot_remove_inherited_items);
Items.RemoveAt(index);
} else {
if (!entry.Value.ElementPresent)
CheckLockedElement(_removeElement, null);
entry.EntryType = EntryType.Removed;
_removedItemCount++;
}
break;
case EntryType.Removed:
throw new ConfigurationErrorsException(System.SR.Config_base_collection_entry_already_removed);
default:
if (CollectionType != ConfigurationElementCollectionType.AddRemoveClearMap && CollectionType != ConfigurationElementCollectionType.AddRemoveClearMapAlternate)
throw new ConfigurationErrorsException(System.SR.Config_base_collection_elements_may_not_be_removed);
entry.EntryType = EntryType.Removed;
_removedItemCount++;
break;
}
_modified = true;
}
protected internal override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey)
{
ConfigurationElementCollectionType collectionType = CollectionType;
bool flag = false;
flag |= base.SerializeElement(writer, serializeCollectionKey);
if ((collectionType == ConfigurationElementCollectionType.AddRemoveClearMap || collectionType == ConfigurationElementCollectionType.AddRemoveClearMapAlternate) && _emitClearTag && _clearElement.Length != 0) {
if (writer != null) {
writer.WriteStartElement(_clearElement);
writer.WriteEndElement();
}
flag = true;
}
foreach (Entry item in Items) {
switch (collectionType) {
case ConfigurationElementCollectionType.BasicMap:
case ConfigurationElementCollectionType.BasicMapAlternate:
if (item.EntryType == EntryType.Added || item.EntryType == EntryType.Replaced) {
if (!string.IsNullOrEmpty(ElementName)) {
if (BaseConfigurationRecord.IsReservedAttributeName(ElementName))
throw new ArgumentException(System.SR.Format(System.SR.Basicmap_item_name_reserved, ElementName));
flag |= item.Value.SerializeToXmlElement(writer, ElementName);
} else
flag |= item.Value.SerializeElement(writer, false);
}
break;
case ConfigurationElementCollectionType.AddRemoveClearMap:
case ConfigurationElementCollectionType.AddRemoveClearMapAlternate:
if ((item.EntryType == EntryType.Removed || item.EntryType == EntryType.Replaced) && item.Value != null) {
writer?.WriteStartElement(_removeElement);
item.Value.SerializeElement(writer, true);
writer?.WriteEndElement();
flag = true;
}
if (item.EntryType == EntryType.Added || item.EntryType == EntryType.Replaced)
flag |= item.Value.SerializeToXmlElement(writer, _addElement);
break;
}
}
return flag;
}
protected override bool OnDeserializeUnrecognizedElement(string elementName, XmlReader reader)
{
if (CollectionType == ConfigurationElementCollectionType.AddRemoveClearMap || CollectionType == ConfigurationElementCollectionType.AddRemoveClearMapAlternate) {
if (elementName == _addElement) {
ConfigurationElement configurationElement = CallCreateNewElement();
configurationElement.ResetLockLists(this);
configurationElement.DeserializeElement(reader, false);
BaseAdd(configurationElement);
} else if (elementName == _removeElement) {
ConfigurationElement configurationElement2 = CallCreateNewElement();
configurationElement2.ResetLockLists(this);
configurationElement2.DeserializeElement(reader, true);
if (IsElementRemovable(configurationElement2))
BaseRemove(GetElementKeyInternal(configurationElement2), false);
} else {
if (elementName != _clearElement)
return false;
if (reader.AttributeCount > 0 && reader.MoveToNextAttribute()) {
string name = reader.Name;
throw new ConfigurationErrorsException(System.SR.Format(System.SR.Config_base_unrecognized_attribute, name), reader);
}
CheckLockedElement(elementName, reader);
reader.MoveToElement();
BaseClear();
_emitClearTag = true;
}
} else if (elementName == ElementName) {
if (BaseConfigurationRecord.IsReservedAttributeName(elementName))
throw new ArgumentException(System.SR.Format(System.SR.Basicmap_item_name_reserved, elementName));
ConfigurationElement configurationElement3 = CallCreateNewElement();
configurationElement3.ResetLockLists(this);
configurationElement3.DeserializeElement(reader, false);
BaseAdd(configurationElement3);
} else {
if (!IsElementName(elementName))
return false;
if (BaseConfigurationRecord.IsReservedAttributeName(elementName))
throw new ArgumentException(System.SR.Format(System.SR.Basicmap_item_name_reserved, elementName));
ConfigurationElement configurationElement4 = CallCreateNewElement(elementName);
configurationElement4.ResetLockLists(this);
configurationElement4.DeserializeElement(reader, false);
BaseAdd(-1, configurationElement4);
}
return true;
}
private ConfigurationElement CallCreateNewElement(string elementName)
{
ConfigurationElement configurationElement = CreateNewElement(elementName);
configurationElement.AssociateContext(_configRecord);
configurationElement.CallInit();
return configurationElement;
}
private ConfigurationElement CallCreateNewElement()
{
ConfigurationElement configurationElement = CreateNewElement();
configurationElement.AssociateContext(_configRecord);
configurationElement.CallInit();
return configurationElement;
}
protected virtual ConfigurationElement CreateNewElement(string elementName)
{
return CreateNewElement();
}
protected abstract ConfigurationElement CreateNewElement();
protected abstract object GetElementKey(ConfigurationElement element);
internal object GetElementKeyInternal(ConfigurationElement element)
{
object elementKey = GetElementKey(element);
if (elementKey == null)
throw new ConfigurationErrorsException(System.SR.Config_base_invalid_element_key);
return elementKey;
}
protected virtual bool IsElementRemovable(ConfigurationElement element)
{
return true;
}
private bool CompareKeys(object key1, object key2)
{
if (_comparer != null)
return _comparer.Compare(key1, key2) == 0;
return key1.Equals(key2);
}
protected virtual bool IsElementName(string elementName)
{
return false;
}
internal bool IsLockableElement(string elementName)
{
if (CollectionType == ConfigurationElementCollectionType.AddRemoveClearMap || CollectionType == ConfigurationElementCollectionType.AddRemoveClearMapAlternate) {
if (!(elementName == AddElementName) && !(elementName == RemoveElementName))
return elementName == ClearElementName;
return true;
}
if (!(elementName == ElementName))
return IsElementName(elementName);
return true;
}
}
}