mirror of https://github.com/icsharpcode/ILSpy.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
3.8 KiB
119 lines
3.8 KiB
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) |
|
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) |
|
|
|
using System; |
|
using System.Collections.Generic; |
|
|
|
namespace ICSharpCode.AvalonEdit.Xml |
|
{ |
|
/// <summary> |
|
/// Specailized attribute collection with attribute name caching |
|
/// </summary> |
|
public class AXmlAttributeCollection: FilteredCollection<AXmlAttribute, AXmlObjectCollection<AXmlObject>> |
|
{ |
|
/// <summary> Empty unbound collection </summary> |
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", |
|
Justification = "InsertItem prevents modifying the Empty collection")] |
|
public static readonly AXmlAttributeCollection Empty = new AXmlAttributeCollection(); |
|
|
|
/// <summary> Create unbound collection </summary> |
|
protected AXmlAttributeCollection() {} |
|
|
|
/// <summary> Wrap the given collection. Non-attributes are filtered </summary> |
|
public AXmlAttributeCollection(AXmlObjectCollection<AXmlObject> source): base(source) {} |
|
|
|
/// <summary> Wrap the given collection. Non-attributes are filtered. Items not matching the condition are filtered. </summary> |
|
public AXmlAttributeCollection(AXmlObjectCollection<AXmlObject> source, Predicate<object> condition): base(source, condition) {} |
|
|
|
Dictionary<string, List<AXmlAttribute>> hashtable = new Dictionary<string, List<AXmlAttribute>>(); |
|
|
|
void AddToHashtable(AXmlAttribute attr) |
|
{ |
|
string localName = attr.LocalName; |
|
if (!hashtable.ContainsKey(localName)) { |
|
hashtable[localName] = new List<AXmlAttribute>(1); |
|
} |
|
hashtable[localName].Add(attr); |
|
} |
|
|
|
void RemoveFromHashtable(AXmlAttribute attr) |
|
{ |
|
string localName = attr.LocalName; |
|
hashtable[localName].Remove(attr); |
|
} |
|
|
|
static List<AXmlAttribute> NoAttributes = new List<AXmlAttribute>(); |
|
|
|
/// <summary> |
|
/// Get all attributes with given local name. |
|
/// Hash table is used for lookup so this is cheap. |
|
/// </summary> |
|
public IEnumerable<AXmlAttribute> GetByLocalName(string localName) |
|
{ |
|
if (hashtable.ContainsKey(localName)) { |
|
return hashtable[localName]; |
|
} else { |
|
return NoAttributes; |
|
} |
|
} |
|
|
|
/// <inheritdoc/> |
|
protected override void ClearItems() |
|
{ |
|
foreach(AXmlAttribute item in this) { |
|
RemoveFromHashtable(item); |
|
item.Changing -= item_Changing; |
|
item.Changed -= item_Changed; |
|
} |
|
base.ClearItems(); |
|
} |
|
|
|
/// <inheritdoc/> |
|
protected override void InsertItem(int index, AXmlAttribute item) |
|
{ |
|
// prevent insertions into the static 'Empty' instance |
|
if (this == Empty) |
|
throw new NotSupportedException("Cannot insert into AXmlAttributeCollection.Empty"); |
|
|
|
AddToHashtable(item); |
|
item.Changing += item_Changing; |
|
item.Changed += item_Changed; |
|
base.InsertItem(index, item); |
|
} |
|
|
|
/// <inheritdoc/> |
|
protected override void RemoveItem(int index) |
|
{ |
|
RemoveFromHashtable(this[index]); |
|
this[index].Changing -= item_Changing; |
|
this[index].Changed -= item_Changed; |
|
base.RemoveItem(index); |
|
} |
|
|
|
/// <inheritdoc/> |
|
protected override void SetItem(int index, AXmlAttribute item) |
|
{ |
|
RemoveFromHashtable(this[index]); |
|
this[index].Changing -= item_Changing; |
|
this[index].Changed -= item_Changed; |
|
|
|
AddToHashtable(item); |
|
item.Changing += item_Changing; |
|
item.Changed += item_Changed; |
|
base.SetItem(index, item); |
|
} |
|
|
|
// Every item in the collection should be registered to these handlers |
|
// so that we can handle renames |
|
|
|
void item_Changing(object sender, AXmlObjectEventArgs e) |
|
{ |
|
RemoveFromHashtable((AXmlAttribute)e.Object); |
|
} |
|
|
|
void item_Changed(object sender, AXmlObjectEventArgs e) |
|
{ |
|
AddToHashtable((AXmlAttribute)e.Object); |
|
} |
|
} |
|
}
|
|
|