2 using System.Collections;
3 using System.Collections.Generic;
9 public class MCharTable : IEnumerable
11 private static readonly int[] nchars
12 = new int[] { 0x110000, 0x10000, 0x1000, 0x80 };
13 private static readonly int[] slots
14 = new int[] { 17, 16, 32, 128 };
15 private static readonly int[] mask
16 = new int[] { 0x11FFFF, 0xFFFF, 0xFFF, 0x7F };
17 private static readonly int[] shift
18 = new int[] { 16, 12, 7, 0 };
20 private int index (int c) { return ((c & mask[depth]) >> shift[depth]); }
22 private MCharTable parent;
24 private int min_char, max_char;
25 private object[] contents;
33 contents = new object[slots[0]];
36 private MCharTable (MCharTable parent, int min_char, object value)
39 this.min_char = min_char;
40 depth = parent.depth + 1;
41 max_char = min_char + nchars[depth] - 1;
42 contents = new object[slots[depth]];
43 for (int i = 0; i < slots[depth]; i++)
47 private object Get (int c)
49 object slot = contents[index (c)];
50 if (slot is MCharTable)
51 return ((MCharTable) slot).Get (c);
55 private void Set (int c, object value)
58 contents[c & mask[3]] = value;
62 int offset = depth == 0 ? 0 : min_char;
64 if (! (contents[i] is MCharTable))
65 contents[i] = new MCharTable (this, offset + i << shift[depth],
67 ((MCharTable) contents[i]).Set (c, value);
71 public object this[int c]
74 if (c < 0 || c > 0x10FFFF)
75 throw new ArgumentException ("Invalid character: " + c);
76 if (min_char > c || max_char < c)
82 if (c < 0 || c > 0x10FFFF)
83 throw new ArgumentException ("Invalid character: " + c);
84 if (value is MCharTable)
85 throw new ArgumentException ("Invalid value type: MCharTable");
94 private class MCharTableIT
98 public MCharTable table;
100 public MCharTableIT (int c, object value, MCharTable table)
107 public override string ToString ()
109 return (String.Format ("<{0:X},{1}>", c, value));
113 private bool Next (MCharTableIT it)
115 Console.WriteLine ("Depth:{0} ({1:X}-{2:X}) IT:{3}", depth, min_char, max_char, it);
117 return (parent != null ? parent.Next (it) : false);
120 for (int i = index (it.c);
121 i < slots[depth] && (value = contents[i]) == null;
122 i++, it.c = min_char + i << shift[depth]);
123 Console.WriteLine ("IT:{1}", depth, it);
125 return (parent != null ? parent.Next (it) : false);
126 if (value is MCharTable)
127 return ((MCharTable) value).Next (it);
133 // for IEnumerable interface
134 public IEnumerator GetEnumerator()
136 return new MCharTableEnum (this);
139 private class MCharTableEnum : IEnumerator
141 private MCharTable table;
142 private MCharTableIT it;
144 public MCharTableEnum (MCharTable table)
147 it = new MCharTableIT (-1, null, table);
150 public bool MoveNext ()
153 return it.table.Next (it);
162 public KeyValuePair<int, object> Current
164 get { return new KeyValuePair<int, object> (it.c, it.value); }