8 public enum MTextFormat
10 MTEXT_FORMAT_US_ASCII,
12 MTEXT_FORMAT_UTF_16BE,
13 MTEXT_FORMAT_UTF_16LE,
14 MTEXT_FORMAT_UTF_32BE,
15 MTEXT_FORMAT_UTF_32LE,
22 public enum MTextFormat format;
25 private class MTextPlist : MPlist
27 public class MInterval
31 public int start, end;
32 public MInterval prev, next;
37 public MTextPlist (MText mt)
39 head = tail = new MInterval ();
41 head.end = mt.sb.Length;
45 private StringBuilder sb;
47 private int cache_pos;
48 private int cache_idx;
49 private MTextPlist plist;
50 private bool unmodifiable;
52 private static UTF8Encoding utf8 = new UTF8Encoding ();
54 private static int count_chars (String str)
56 int len = str.Length, n = 0;
58 for (int i = 0; i < len; i++)
59 n += surrogate_high_p (str[i]) ? 2 : 1;
63 private static int count_chars (StringBuilder str)
65 int len = str.Length, n = 0;
67 for (int i = 0; i < len; i++)
68 n += surrogate_high_p (str[i]) ? 2 : 1;
74 sb = new StringBuilder ();
77 public MText (byte[] str)
79 sb = new StringBuilder (utf8.GetString (str));
80 nchars = count_chars (sb);
83 public MText (String str)
85 sb = new StringBuilder (str);
86 nchars = count_chars (str);
89 public MText (StringBuilder str)
92 nchars = count_chars (str);
95 public static MText operator+ (MText mt1, MText mt2)
97 MText mt = new MText (mt1.sb);
99 mt.sb.Append (mt2.sb);
100 mt.nchars = mt1.nchars + mt2.nchars;
104 public override string ToString ()
106 return sb.ToString ();
109 private static bool surrogate_high_p (char c)
111 return (c >= 0xD800 && c < 0xDC00);
114 private static bool surrogate_low_p (char c)
116 return (c >= 0xDC00 && c < 0xE000);
119 private static int inc_idx (StringBuilder sb, int i)
121 return (i + (surrogate_high_p (sb[i]) ? 2 : 1));
124 private static int dec_idx (StringBuilder sb, int i)
126 return (i - (surrogate_low_p (sb[i - 1]) ? 2 : 1));
129 private static int pos_to_idx (MText mt, int pos)
131 if (pos == mt.cache_pos)
137 if (pos < mt.cache_pos)
139 if (mt.cache_pos == mt.cache_idx)
141 if (pos < mt.cache_pos - pos)
148 p = mt.cache_pos; i = mt.cache_idx;
154 if (mt.nchars - mt.cache_pos == mt.sb.Length - mt.cache_idx)
155 return (mt.cache_idx + pos - mt.cache_pos);
156 if (pos - mt.cache_pos < mt.nchars - pos)
158 p = mt.cache_pos; i = mt.cache_idx;
163 p = mt.nchars; i = mt.sb.Length;
168 for (; p < pos; i = inc_idx (mt.sb, i), p++);
170 for (; p > pos; i = dec_idx (mt.sb, i), p--);
176 private void insert (int pos, MText mt2, int from, int to)
178 int pos_idx = pos_to_idx (this, pos);
179 int from_idx = pos_to_idx (mt2, from);
180 int to_idx = pos_to_idx (mt2, to);
182 sb.Insert (pos_idx, mt2.sb.ToString (from_idx, to_idx - from_idx));
186 public int this[int i]
189 i = pos_to_idx (this, i);
192 if (surrogate_high_p (sb[i]))
194 sb[i] = (char) value;
198 char high = (char) (0xD800 + ((value - 0x10000) >> 10));
199 char low = (char) (0xDC00 + ((value - 0x10000) & 0x3FF));
201 if (! surrogate_high_p (sb[i]))
208 i = pos_to_idx (this, i);
209 return (surrogate_high_p (sb[i])
210 ? ((sb[i] - 0xD800) << 10) + (sb[i + 1] - 0xDC00) + 0x10000
217 return (new MText (sb.ToString ()));
220 public MText ins (int pos, ref MText mt)
222 insert (pos, mt, 0, mt.nchars);
226 public MText ins (int pos, ref MText mt, int from, int to)
228 insert (pos, mt, from, to);
232 public MText del (int from, int to)
234 sb.Remove (from, pos_to_idx (this, to) - pos_to_idx (this, from));
240 public class MTextProperty