Mercurial > hg > ucis.core
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 } |