Mercurial > hg > ucis.core
diff Pml/Elements/Array.cs @ 0:3ab940a0c7a0
Initial commit
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Tue, 11 Sep 2012 16:28:53 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Pml/Elements/Array.cs Tue Sep 11 16:28:53 2012 +0200 @@ -0,0 +1,281 @@ +using System; +using System.Collections; +using System.Collections.Generic; +//using KvpType = System.Collections.Generic.KeyValuePair<string, UCIS.Pml.PmlElement>; +using KvpType = UCIS.Pml.PmlArray.KeyValuePair; + +namespace UCIS.Pml { + public class PmlArray : PmlElement, IDictionary<string, PmlElement>, IList<KvpType>, IList<PmlElement>, ICollection<String> { + /* Internal variables */ + private List<KvpType> _items = new List<KvpType>(); + private int _indexed = 0; + + /* Internal key-value pair structure */ + public class KeyValuePair { + internal KeyValuePair(string key, PmlElement value) { this.Key = key; this.Value = value; } + public string Key { get; set; } + public PmlElement Value { get; set; } + } + + /* Constructors */ + public PmlArray() { + } + public PmlArray(params KeyValuePair<string, PmlElement>[] elements) { + foreach (KeyValuePair<string, PmlElement> item in elements) Add(item); + } + public PmlArray(IEnumerable<KeyValuePair<string, PmlElement>> elements) { + foreach (KeyValuePair<String, PmlElement> item in elements) Add(item); + } + public PmlArray(params PmlElement[] elements) { + foreach (PmlElement item in elements) Add(item); + } + public PmlArray(IEnumerable<PmlElement> elements) { + foreach (PmlElement item in elements) Add(item); + } + public PmlArray(String key1, PmlElement val1) { + Add(key1, val1); + } + public PmlArray(String key1, PmlElement val1, String key2, PmlElement val2) { + Add(key1, val1); + Add(key2, val2); + } + public PmlArray(String key1, PmlElement val1, String key2, PmlElement val2, String key3, PmlElement val3) { + Add(key1, val1); + Add(key2, val2); + Add(key3, val3); + } + public PmlArray(params Object[] interleavedKeyValue) { + for (int i = 0; i < interleavedKeyValue.Length; ) { + Add(interleavedKeyValue[i++] as String, interleavedKeyValue[i++]); + } + } + public PmlArray(String[] keys, params PmlElement[] values) { + if (keys.Length != values.Length) throw new ArgumentException("Length of keys array does not match length of values array"); + for (int i = 0; i < keys.Length; i++) { Add(keys[i] as String, values[i]); } + } + + public bool IsIndexed { + get { + if (_indexed == -1) { + _indexed = 0; + foreach (KvpType kvp in _items) { + if (kvp.Key != null && kvp.Key.Length > 0) { + _indexed = 1; + break; + } + } + } + return _indexed != 0; + } + } + + /* PmlElement implementation */ + protected override object GetValue() { return _items; } + public override PmlElement GetChild(string Name) { return GetItem(Name); } + public override PmlElement GetChild(int index) { return GetItem(index); } + public override object ToNumeric() { return _items.Count; } + public override PmlElementType Type { get { return PmlElementType.Dictionary; } } + + /* Internal KVP lookup */ + private KvpType GetKVP(string name) { + return _items.Find(delegate(KvpType kvp) { return (kvp.Key == name); }); + } + private KvpType GetKVP(PmlElement value) { + return _items.Find(delegate(KvpType kvp) { return (kvp.Value == value); }); + } + private KvpType GetKVP(int index) { + if (index < 0 || index >= _items.Count) return null; + return _items[index]; + } + + /* Item retrieval */ + public PmlElement GetItem(string name) { + KvpType kvp = GetKVP(name); + return kvp == null ? null : kvp.Value; + } + public PmlElement GetItem(int index) { + if (index < 0 || index >= _items.Count) return null; + return _items[index].Value; + } + public bool TryGetValue(string key, out PmlElement value) { + value = GetItem(key); + return (value != null); + } + + /* Array implementation */ + public PmlElement this[string key] { + get { return GetItem(key); } + set { + Remove(key); + Add(key, value); + } + } + public KvpType this[int id] { + get { return GetKVP(id); } + set { _items[id] = value; } + } + PmlElement IList<PmlElement>.this[int id] { + get { return GetItem(id); } + set { + KvpType item = GetKVP(id); + item = new KvpType(item == null ? null : item.Key, value); + _items[id] = item; + } + } + + /* Add implementations */ + public void Add(KvpType kvp) { //Final Add method, handles all additions (except insertions!) + if (_indexed == 0 && kvp.Key != null && kvp.Key.Length > 0) _indexed = 1; + _items.Add(kvp); + } + + public PmlElement Add(string Key, PmlElement Element) { + if (Element == null) Element = new PmlNull(); + Add(new KvpType(Key, Element)); + return Element; + } + + public PmlElement Add(string key, Object value) { + PmlElement el; + if (value == null) { + el = new PmlNull(); + } else if (value is PmlElement) { + el = value as PmlElement; + } else if (value is String) { + el = new PmlString(value as string); + } else if (value is Int32 || value is Int64) { + el = new PmlNumber((Int64)value); + } else if (value is UInt32 || value is UInt32) { + el = new PmlNumber((UInt64)value); + } else { + el = new PmlString(value.ToString()); + } + return Add(key, el); + } + public PmlElement Add(string Key, string Element) { return Add(Key, new PmlString(Element)); } + public PmlElement Add(string Key, long Element) { return Add(Key, new PmlInteger(Element)); } + public PmlElement Add(string Key, ulong Element) { return Add(Key, new PmlInteger(Element)); } + + public PmlElement Add(PmlElement Element) { return Add(null, Element); } + public PmlElement Add(object Element) { return Add(null, Element); } + public PmlElement Add(string Element) { return Add(new PmlString(Element)); } + public PmlElement Add(long Element) { return Add(new PmlInteger(Element)); } + public PmlElement Add(ulong Element) { return Add(new PmlInteger(Element)); } + + public void Add(KeyValuePair<string, PmlElement> item) { Add(item.Key, item.Value); } + + void ICollection<PmlElement>.Add(PmlElement item) { Add(item); } + void IDictionary<String, PmlElement>.Add(string key, PmlElement value) { Add(key, value); } + + /* Insert implementations */ + private void Insert(int index, KvpType kvp) { + if (kvp.Key != null && kvp.Key.Length > 0 && _indexed == 0) _indexed = 1; + _items.Insert(index, kvp); + } + void IList<KvpType>.Insert(int index, KvpType value) { Insert(index, value); } + void IList<PmlElement>.Insert(int index, PmlElement value) { Insert(index, new KvpType(null, value)); } + + /* Remove */ + public bool Remove(KvpType item) { + _indexed = -1; + return _items.Remove(item); + } + public void RemoveAt(int index) { + _indexed = -1; + _items.RemoveAt(index); + } + public bool Remove(PmlElement item) { + KvpType kvp = GetKVP(item); + if (kvp == null) return false; + return Remove(kvp); + } + public bool Remove(string Key) { + KvpType kvp = GetKVP(Key); + if (kvp == null) return false; + return Remove(kvp); + } + bool ICollection<KeyValuePair<string, PmlElement>>.Remove(KeyValuePair<string, PmlElement> kvp) { return Remove(kvp.Key); } + + public void Clear() { + _indexed = 0; + _items.Clear(); + } + + /* Contains */ + public bool Contains(PmlElement item) { return GetKVP(item) != null; } + public bool Contains(string key) { return GetKVP(key) != null; } + bool IDictionary<String, PmlElement>.ContainsKey(string key) { return Contains(key); } + bool ICollection<KvpType>.Contains(KvpType kvp) { return _items.Contains(kvp); } + bool ICollection<KeyValuePair<String, PmlElement>>.Contains(KeyValuePair<String, PmlElement> kvp) { return Contains(kvp.Key); } + + /* Index lookup */ + public int IndexOf(PmlElement value) { return _items.FindIndex(delegate(KvpType kvp) { return (kvp.Value == value); }); } + int IList<KvpType>.IndexOf(KvpType value) { return _items.IndexOf(value); } + + /* Copy operations */ + public void CopyTo(KvpType[] array, int offset) { + _items.CopyTo(array, offset); + } + public void CopyTo(PmlElement[] array, int offset) { + foreach (KvpType kvp in _items) array[offset++] = kvp.Value; + } + void ICollection<String>.CopyTo(string[] array, int offset) { + foreach (KvpType kvp in _items) array[offset++] = kvp.Key; + } + void ICollection<KeyValuePair<string, PmlElement>>.CopyTo(KeyValuePair<string, PmlElement>[] array, int offset) { + foreach (KvpType kvp in _items) array[offset++] = new KeyValuePair<string,PmlElement>(kvp.Key, kvp.Value); + } + + /* Dictionary props */ + public ICollection<PmlElement> Values { get { return this as ICollection<PmlElement>; } } + public ICollection<String> Keys { get { return this as ICollection<String>; } } + + /* Stuf... */ + public int Count { get { return _items.Count; } } + public bool IsReadOnly { get { return false; } } + void ICollection<String>.Add(string value) { throw new NotImplementedException(); } + + /* Enumerators */ + IEnumerator<KvpType> IEnumerable<KvpType>.GetEnumerator() { return _items.GetEnumerator(); } + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } + public IEnumerator<PmlElement> GetEnumerator() { return new ValueEnumerator(this); } + IEnumerator<String> IEnumerable<String>.GetEnumerator() { return new KeyEnumerator(this); } + IEnumerator<KeyValuePair<string, PmlElement>> IEnumerable<KeyValuePair<string, PmlElement>>.GetEnumerator() { return new KvpEnumerator(this); } + + private class KeyEnumerator : IEnumerator<String> { + protected IEnumerator<KvpType> _enum; + internal KeyEnumerator(PmlArray array) { _enum = array._items.GetEnumerator(); } + private KvpType KVP { get { return _enum.Current; } } + public bool MoveNext() { return _enum.MoveNext(); } + public void Reset() { _enum.Reset(); } + public void Dispose() { _enum.Dispose(); } + Object IEnumerator.Current { get { return Current; } } + + public String Current { get { return KVP == null ? null : KVP.Key; } } + } + private class ValueEnumerator : IEnumerator<PmlElement> { + protected IEnumerator<KvpType> _enum; + internal ValueEnumerator(PmlArray array) { _enum = array._items.GetEnumerator(); } + private KvpType KVP { get { return _enum.Current; } } + public bool MoveNext() { return _enum.MoveNext(); } + public void Reset() { _enum.Reset(); } + public void Dispose() { _enum.Dispose(); } + Object IEnumerator.Current { get { return Current; } } + + public PmlElement Current { get { return KVP == null ? null : KVP.Value; } } + } + private class KvpEnumerator : IEnumerator<KeyValuePair<String, PmlElement>> { + protected IEnumerator<KvpType> _enum; + internal KvpEnumerator(PmlArray array) { _enum = array._items.GetEnumerator(); } + private KvpType KVP { get { return _enum.Current; } } + public bool MoveNext() { return _enum.MoveNext(); } + public void Reset() { _enum.Reset(); } + public void Dispose() { _enum.Dispose(); } + Object IEnumerator.Current { get { return Current; } } + + public KeyValuePair<String, PmlElement> Current { get { + return KVP == null ? default(KeyValuePair<String, PmlElement>) : new KeyValuePair<String, PmlElement>(KVP.Key, KVP.Value); + } } + } + } +} \ No newline at end of file