using System; using System.Collections; using System.Text; namespace RusticiSoftware.Translator { // Implements a hierarchy of directories. public class DirectoryHT : IDictionary { private DirectoryHT _parent = null; private Hashtable leaves = new Hashtable(); private Hashtable children = new Hashtable(); public DirectoryHT(DirectoryHT p) { _parent = p; } public DirectoryHT() : this(null) { } public Hashtable Leaves { get { return leaves; } } // p is key to a sub directory public DirectoryHT subDir(string p) { string[] components = p.Split(new char[] { '.' }, 2); if (components.Length == 1) { return (DirectoryHT) children[components[0]]; } else { DirectoryHT child = (DirectoryHT)children[components[0]]; return (child == null ? null : child.subDir(components[1])); } } #region IDictionary Members public void Add(object key, object value) { if (!(key is string)) throw new Exception("The method or operation is not implemented."); string[] components = ((string)key).Split(new char[] { '.' }, 2); if (components.Length == 1) { leaves[components[0]] = value; } else { if (children[components[0]] == null) children[components[0]] = new DirectoryHT(this); ((DirectoryHT)children[components[0]]).Add(components[1], value); } } public void Clear() { leaves.Clear(); children.Clear(); } public bool Contains(object key) { if (!(key is string)) throw new Exception("The method or operation is not implemented."); string[] components = ((String)key).Split(new char[] { '.' }, 2); if (components.Length == 1) { return leaves.Contains(components[0]); } else { return ((DirectoryHT)children[components[0]]).Contains(components[1]); } } public IDictionaryEnumerator GetEnumerator() { IDictionaryEnumerator[] des = new IDictionaryEnumerator[1 + children.Count]; string[] pres = new string[1 + children.Count]; int i = 1; pres[0] = ""; des[0] = leaves.GetEnumerator(); foreach (DictionaryEntry de in children) { pres[i] = ((string)de.Key) + "."; des[i] = ((DirectoryHT)de.Value).GetEnumerator(); i++; } return new DirectoryHTEnumerator(pres,des); } public bool IsFixedSize { get { return false; } } public bool IsReadOnly { get { return false; } } public ICollection Keys { get { ArrayList keys = new ArrayList(); foreach (object k in leaves.Keys) keys.Add(k); foreach (DictionaryEntry de in children) foreach (string k in ((DirectoryHT)de.Value).Keys) keys.Add(de.Key + "." + k); return keys; } } public void Remove(object key) { if (!(key is string)) throw new Exception("The method or operation is not implemented."); string[] components = ((string)key).Split(new char[] { '.' }, 2); if (components.Length == 1) { leaves.Remove(components[0]); } else { ((DirectoryHT)children[components[0]]).Remove(components[1]); } } public ICollection Values { get { ArrayList vals = new ArrayList(); foreach (object v in leaves.Values) vals.Add(v); foreach (DictionaryEntry de in children) foreach (object v in ((DirectoryHT)de.Value).Values) vals.Add(v); return vals; } } public object this[object key] { get { if (!(key is string)) throw new Exception("The method or operation is not implemented."); string[] components = ((string)key).Split(new char[] { '.' }, 2); if (components.Length == 1) { object val = leaves[components[0]]; return (val != null ? val : children[components[0]]); } else { DirectoryHT child = (DirectoryHT)children[components[0]]; return (child == null ? null : child[components[1]]); } } set { Add(key, value); } } #endregion #region ICollection Members public void CopyTo(Array array, int index) { throw new Exception("The method or operation is not implemented."); } public int Count { get { int count = leaves.Count; foreach (DirectoryHT c in children.Values) count += c.Count; return count; } } public bool IsSynchronized { get { throw new Exception("The method or operation is not implemented."); } } public object SyncRoot { get { throw new Exception("The method or operation is not implemented."); } } #endregion #region IEnumerable Members IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } #endregion } public class DirectoryHTEnumerator : IDictionaryEnumerator { private int _pos = 0; private string[] _prefixes; private IDictionaryEnumerator[] _enums; public DirectoryHTEnumerator(string[] pres, IDictionaryEnumerator[] des) { _prefixes = pres; _enums = des; } #region IDictionaryEnumerator Members public DictionaryEntry Entry { get { return (DictionaryEntry)Current; } } public object Key { get { return Entry.Key; } } public object Value { get { return Entry.Value; } } #endregion #region IEnumerator Members public object Current { get { ValidateIndex(); return new DictionaryEntry(_prefixes[_pos] + (string)((DictionaryEntry)_enums[_pos].Current).Key, ((DictionaryEntry)_enums[_pos].Current).Value); } } public bool MoveNext() { if (_pos >= _enums.Length) return false; while (_pos < _enums.Length && !_enums[_pos].MoveNext()) _pos++; return _pos != _enums.Length; } public void Reset() { _pos = 0; } // Validate the enumeration index and throw an exception if the index is out of range. private void ValidateIndex() { if (_pos < 0 || _pos >= _enums.Length) throw new InvalidOperationException("Enumerator is before or after the collection."); } #endregion } }