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 private static bool surrogate_high_p (char c)
106 return (c >= 0xD800 && c < 0xDC00);
109 private static bool surrogate_low_p (char c)
111 return (c >= 0xDC00 && c < 0xE000);
114 private static int inc_idx (StringBuilder sb, int i)
116 return (i + (surrogate_high_p (sb[i]) ? 2 : 1));
119 private static int dec_idx (StringBuilder sb, int i)
121 return (i - (surrogate_low_p (sb[i - 1]) ? 2 : 1));
124 private static int pos_to_idx (MText mt, int pos)
126 if (pos == mt.cache_pos)
132 if (pos < mt.cache_pos)
134 if (mt.cache_pos == mt.cache_idx)
136 if (pos < mt.cache_pos - pos)
143 p = mt.cache_pos; i = mt.cache_idx;
149 if (mt.nchars - mt.cache_pos == mt.sb.Length - mt.cache_idx)
150 return (mt.cache_idx + pos - mt.cache_pos);
151 if (pos - mt.cache_pos < mt.nchars - pos)
153 p = mt.cache_pos; i = mt.cache_idx;
158 p = mt.nchars; i = mt.sb.Length;
163 for (; p < pos; i = inc_idx (mt.sb, i), p++);
165 for (; p > pos; i = dec_idx (mt.sb, i), p--);
171 private void insert (int pos, MText mt2, int from, int to)
173 int pos_idx = pos_to_idx (this, pos);
174 int from_idx = pos_to_idx (mt2, from);
175 int to_idx = pos_to_idx (mt2, to);
177 sb.Insert (pos_idx, mt2.sb.ToString (from_idx, to_idx - from_idx));
181 public int this[int i]
184 i = pos_to_idx (this, i);
186 sb[i] = (char) value;
189 char high = (char) (0xD800 + ((i - 0x10000) >> 10));
190 char low = (char) (0xDC00 + ((i - 0x10000) & 0x3FF));
192 if (! surrogate_high_p (sb[i]))
199 i = pos_to_idx (this, i);
200 return (surrogate_high_p (sb[i])
201 ? i = ((sb[i] - 0xD800) << 10) + (sb[i + 1] - 0xDC00) + 0x10000
208 return (new MText (this.sb));
211 public MText ins (int pos, ref MText mt)
213 insert (pos, mt, 0, mt.nchars);
217 public MText ins (int pos, ref MText mt, int from, int to)
219 insert (pos, mt, from, to);
223 public MText del (int from, int to)
225 sb.Remove (from, pos_to_idx (this, to) - pos_to_idx (this, from));
231 public class MTextProperty