comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:3ab940a0c7a0
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 //using KvpType = System.Collections.Generic.KeyValuePair<string, UCIS.Pml.PmlElement>;
5 using KvpType = UCIS.Pml.PmlArray.KeyValuePair;
6
7 namespace UCIS.Pml {
8 public class PmlArray : PmlElement, IDictionary<string, PmlElement>, IList<KvpType>, IList<PmlElement>, ICollection<String> {
9 /* Internal variables */
10 private List<KvpType> _items = new List<KvpType>();
11 private int _indexed = 0;
12
13 /* Internal key-value pair structure */
14 public class KeyValuePair {
15 internal KeyValuePair(string key, PmlElement value) { this.Key = key; this.Value = value; }
16 public string Key { get; set; }
17 public PmlElement Value { get; set; }
18 }
19
20 /* Constructors */
21 public PmlArray() {
22 }
23 public PmlArray(params KeyValuePair<string, PmlElement>[] elements) {
24 foreach (KeyValuePair<string, PmlElement> item in elements) Add(item);
25 }
26 public PmlArray(IEnumerable<KeyValuePair<string, PmlElement>> elements) {
27 foreach (KeyValuePair<String, PmlElement> item in elements) Add(item);
28 }
29 public PmlArray(params PmlElement[] elements) {
30 foreach (PmlElement item in elements) Add(item);
31 }
32 public PmlArray(IEnumerable<PmlElement> elements) {
33 foreach (PmlElement item in elements) Add(item);
34 }
35 public PmlArray(String key1, PmlElement val1) {
36 Add(key1, val1);
37 }
38 public PmlArray(String key1, PmlElement val1, String key2, PmlElement val2) {
39 Add(key1, val1);
40 Add(key2, val2);
41 }
42 public PmlArray(String key1, PmlElement val1, String key2, PmlElement val2, String key3, PmlElement val3) {
43 Add(key1, val1);
44 Add(key2, val2);
45 Add(key3, val3);
46 }
47 public PmlArray(params Object[] interleavedKeyValue) {
48 for (int i = 0; i < interleavedKeyValue.Length; ) {
49 Add(interleavedKeyValue[i++] as String, interleavedKeyValue[i++]);
50 }
51 }
52 public PmlArray(String[] keys, params PmlElement[] values) {
53 if (keys.Length != values.Length) throw new ArgumentException("Length of keys array does not match length of values array");
54 for (int i = 0; i < keys.Length; i++) { Add(keys[i] as String, values[i]); }
55 }
56
57 public bool IsIndexed {
58 get {
59 if (_indexed == -1) {
60 _indexed = 0;
61 foreach (KvpType kvp in _items) {
62 if (kvp.Key != null && kvp.Key.Length > 0) {
63 _indexed = 1;
64 break;
65 }
66 }
67 }
68 return _indexed != 0;
69 }
70 }
71
72 /* PmlElement implementation */
73 protected override object GetValue() { return _items; }
74 public override PmlElement GetChild(string Name) { return GetItem(Name); }
75 public override PmlElement GetChild(int index) { return GetItem(index); }
76 public override object ToNumeric() { return _items.Count; }
77 public override PmlElementType Type { get { return PmlElementType.Dictionary; } }
78
79 /* Internal KVP lookup */
80 private KvpType GetKVP(string name) {
81 return _items.Find(delegate(KvpType kvp) { return (kvp.Key == name); });
82 }
83 private KvpType GetKVP(PmlElement value) {
84 return _items.Find(delegate(KvpType kvp) { return (kvp.Value == value); });
85 }
86 private KvpType GetKVP(int index) {
87 if (index < 0 || index >= _items.Count) return null;
88 return _items[index];
89 }
90
91 /* Item retrieval */
92 public PmlElement GetItem(string name) {
93 KvpType kvp = GetKVP(name);
94 return kvp == null ? null : kvp.Value;
95 }
96 public PmlElement GetItem(int index) {
97 if (index < 0 || index >= _items.Count) return null;
98 return _items[index].Value;
99 }
100 public bool TryGetValue(string key, out PmlElement value) {
101 value = GetItem(key);
102 return (value != null);
103 }
104
105 /* Array implementation */
106 public PmlElement this[string key] {
107 get { return GetItem(key); }
108 set {
109 Remove(key);
110 Add(key, value);
111 }
112 }
113 public KvpType this[int id] {
114 get { return GetKVP(id); }
115 set { _items[id] = value; }
116 }
117 PmlElement IList<PmlElement>.this[int id] {
118 get { return GetItem(id); }
119 set {
120 KvpType item = GetKVP(id);
121 item = new KvpType(item == null ? null : item.Key, value);
122 _items[id] = item;
123 }
124 }
125
126 /* Add implementations */
127 public void Add(KvpType kvp) { //Final Add method, handles all additions (except insertions!)
128 if (_indexed == 0 && kvp.Key != null && kvp.Key.Length > 0) _indexed = 1;
129 _items.Add(kvp);
130 }
131
132 public PmlElement Add(string Key, PmlElement Element) {
133 if (Element == null) Element = new PmlNull();
134 Add(new KvpType(Key, Element));
135 return Element;
136 }
137
138 public PmlElement Add(string key, Object value) {
139 PmlElement el;
140 if (value == null) {
141 el = new PmlNull();
142 } else if (value is PmlElement) {
143 el = value as PmlElement;
144 } else if (value is String) {
145 el = new PmlString(value as string);
146 } else if (value is Int32 || value is Int64) {
147 el = new PmlNumber((Int64)value);
148 } else if (value is UInt32 || value is UInt32) {
149 el = new PmlNumber((UInt64)value);
150 } else {
151 el = new PmlString(value.ToString());
152 }
153 return Add(key, el);
154 }
155 public PmlElement Add(string Key, string Element) { return Add(Key, new PmlString(Element)); }
156 public PmlElement Add(string Key, long Element) { return Add(Key, new PmlInteger(Element)); }
157 public PmlElement Add(string Key, ulong Element) { return Add(Key, new PmlInteger(Element)); }
158
159 public PmlElement Add(PmlElement Element) { return Add(null, Element); }
160 public PmlElement Add(object Element) { return Add(null, Element); }
161 public PmlElement Add(string Element) { return Add(new PmlString(Element)); }
162 public PmlElement Add(long Element) { return Add(new PmlInteger(Element)); }
163 public PmlElement Add(ulong Element) { return Add(new PmlInteger(Element)); }
164
165 public void Add(KeyValuePair<string, PmlElement> item) { Add(item.Key, item.Value); }
166
167 void ICollection<PmlElement>.Add(PmlElement item) { Add(item); }
168 void IDictionary<String, PmlElement>.Add(string key, PmlElement value) { Add(key, value); }
169
170 /* Insert implementations */
171 private void Insert(int index, KvpType kvp) {
172 if (kvp.Key != null && kvp.Key.Length > 0 && _indexed == 0) _indexed = 1;
173 _items.Insert(index, kvp);
174 }
175 void IList<KvpType>.Insert(int index, KvpType value) { Insert(index, value); }
176 void IList<PmlElement>.Insert(int index, PmlElement value) { Insert(index, new KvpType(null, value)); }
177
178 /* Remove */
179 public bool Remove(KvpType item) {
180 _indexed = -1;
181 return _items.Remove(item);
182 }
183 public void RemoveAt(int index) {
184 _indexed = -1;
185 _items.RemoveAt(index);
186 }
187 public bool Remove(PmlElement item) {
188 KvpType kvp = GetKVP(item);
189 if (kvp == null) return false;
190 return Remove(kvp);
191 }
192 public bool Remove(string Key) {
193 KvpType kvp = GetKVP(Key);
194 if (kvp == null) return false;
195 return Remove(kvp);
196 }
197 bool ICollection<KeyValuePair<string, PmlElement>>.Remove(KeyValuePair<string, PmlElement> kvp) { return Remove(kvp.Key); }
198
199 public void Clear() {
200 _indexed = 0;
201 _items.Clear();
202 }
203
204 /* Contains */
205 public bool Contains(PmlElement item) { return GetKVP(item) != null; }
206 public bool Contains(string key) { return GetKVP(key) != null; }
207 bool IDictionary<String, PmlElement>.ContainsKey(string key) { return Contains(key); }
208 bool ICollection<KvpType>.Contains(KvpType kvp) { return _items.Contains(kvp); }
209 bool ICollection<KeyValuePair<String, PmlElement>>.Contains(KeyValuePair<String, PmlElement> kvp) { return Contains(kvp.Key); }
210
211 /* Index lookup */
212 public int IndexOf(PmlElement value) { return _items.FindIndex(delegate(KvpType kvp) { return (kvp.Value == value); }); }
213 int IList<KvpType>.IndexOf(KvpType value) { return _items.IndexOf(value); }
214
215 /* Copy operations */
216 public void CopyTo(KvpType[] array, int offset) {
217 _items.CopyTo(array, offset);
218 }
219 public void CopyTo(PmlElement[] array, int offset) {
220 foreach (KvpType kvp in _items) array[offset++] = kvp.Value;
221 }
222 void ICollection<String>.CopyTo(string[] array, int offset) {
223 foreach (KvpType kvp in _items) array[offset++] = kvp.Key;
224 }
225 void ICollection<KeyValuePair<string, PmlElement>>.CopyTo(KeyValuePair<string, PmlElement>[] array, int offset) {
226 foreach (KvpType kvp in _items) array[offset++] = new KeyValuePair<string,PmlElement>(kvp.Key, kvp.Value);
227 }
228
229 /* Dictionary props */
230 public ICollection<PmlElement> Values { get { return this as ICollection<PmlElement>; } }
231 public ICollection<String> Keys { get { return this as ICollection<String>; } }
232
233 /* Stuf... */
234 public int Count { get { return _items.Count; } }
235 public bool IsReadOnly { get { return false; } }
236 void ICollection<String>.Add(string value) { throw new NotImplementedException(); }
237
238 /* Enumerators */
239 IEnumerator<KvpType> IEnumerable<KvpType>.GetEnumerator() { return _items.GetEnumerator(); }
240 IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
241 public IEnumerator<PmlElement> GetEnumerator() { return new ValueEnumerator(this); }
242 IEnumerator<String> IEnumerable<String>.GetEnumerator() { return new KeyEnumerator(this); }
243 IEnumerator<KeyValuePair<string, PmlElement>> IEnumerable<KeyValuePair<string, PmlElement>>.GetEnumerator() { return new KvpEnumerator(this); }
244
245 private class KeyEnumerator : IEnumerator<String> {
246 protected IEnumerator<KvpType> _enum;
247 internal KeyEnumerator(PmlArray array) { _enum = array._items.GetEnumerator(); }
248 private KvpType KVP { get { return _enum.Current; } }
249 public bool MoveNext() { return _enum.MoveNext(); }
250 public void Reset() { _enum.Reset(); }
251 public void Dispose() { _enum.Dispose(); }
252 Object IEnumerator.Current { get { return Current; } }
253
254 public String Current { get { return KVP == null ? null : KVP.Key; } }
255 }
256 private class ValueEnumerator : IEnumerator<PmlElement> {
257 protected IEnumerator<KvpType> _enum;
258 internal ValueEnumerator(PmlArray array) { _enum = array._items.GetEnumerator(); }
259 private KvpType KVP { get { return _enum.Current; } }
260 public bool MoveNext() { return _enum.MoveNext(); }
261 public void Reset() { _enum.Reset(); }
262 public void Dispose() { _enum.Dispose(); }
263 Object IEnumerator.Current { get { return Current; } }
264
265 public PmlElement Current { get { return KVP == null ? null : KVP.Value; } }
266 }
267 private class KvpEnumerator : IEnumerator<KeyValuePair<String, PmlElement>> {
268 protected IEnumerator<KvpType> _enum;
269 internal KvpEnumerator(PmlArray array) { _enum = array._items.GetEnumerator(); }
270 private KvpType KVP { get { return _enum.Current; } }
271 public bool MoveNext() { return _enum.MoveNext(); }
272 public void Reset() { _enum.Reset(); }
273 public void Dispose() { _enum.Dispose(); }
274 Object IEnumerator.Current { get { return Current; } }
275
276 public KeyValuePair<String, PmlElement> Current { get {
277 return KVP == null ? default(KeyValuePair<String, PmlElement>) : new KeyValuePair<String, PmlElement>(KVP.Key, KVP.Value);
278 } }
279 }
280 }
281 }