using System; using System.Text; using M17N.Core; namespace M17N.Core { #if false public enum MTextFormat { MTEXT_FORMAT_US_ASCII, MTEXT_FORMAT_UTF_8, MTEXT_FORMAT_UTF_16BE, MTEXT_FORMAT_UTF_16LE, MTEXT_FORMAT_UTF_32BE, MTEXT_FORMAT_UTF_32LE, } #endif public class MText { #if false public enum MTextFormat format; #endif private class MTextPlist : MPlist { public class MInterval { MPlist stack; int nprops; public int start, end; public MInterval prev, next; } MInterval head, tail; public MTextPlist (MText mt) { head = tail = new MInterval (); head.start = 0; head.end = mt.sb.Length; } } private StringBuilder sb; private int nchars; private int cache_pos; private int cache_idx; private MTextPlist plist; private static UTF8Encoding utf8 = new UTF8Encoding (); private static UTF32Encoding utf32 = new UTF32Encoding (true, false); private static int count_chars (String str) { int len = str.Length, n = 0; for (int i = 0; i < len; i++) n += surrogate_high_p (str[i]) ? 2 : 1; return n; } private static int count_chars (StringBuilder str) { int len = str.Length, n = 0; for (int i = 0; i < len; i++) n += surrogate_high_p (str[i]) ? 2 : 1; return n; } public MText () { sb = new StringBuilder (); } public MText (byte[] str) { sb = new StringBuilder (utf8.GetString (str)); nchars = count_chars (sb); } public MText (String str) { sb = new StringBuilder (str); nchars = count_chars (str); } public MText (StringBuilder str) { sb = str; nchars = count_chars (str); } public static MText operator+ (MText mt1, MText mt2) { return new MText (mt1.sb + mt2.sb); } private static bool surrogate_high_p (char c) { return (c >= 0xD800 && c < 0xDC00); } private static bool surrogate_low_p (char c) { return (c >= 0xDC00 && c < 0xE000); } private int inc_idx (int i) { return (i + (surrogate_high_p (sb[i]) ? 2 : 1)); } private int dec_idx (int i) { return (i - (surrogate_low_p (sb[i - 1]) ? 2 : 1)); } private int pos_to_idx (int pos) { int p, i; bool forward; if (pos < cache_pos) { if (cache_pos == cache_idx) return cache_idx; if (pos < cache_pos - pos) { p = i = 0; forward = true; } else { p = cache_pos; i = cache_idx; forward = false; } } else { if (nchars - cache_pos == sb.Length - cache_idx) return (cache_idx + pos - cache_pos); if (pos - cache_pos < nchars - pos) { p = cache_pos; i = cache_idx; forward = true; } else { p = nchars; i = sb.Length; forward = false; } } if (forward) for (; p < pos; i = inc_idx (i), p++); else for (; p > pos; i = dec_idx (i), p--); cache_pos = p; cache_idx = i; return i; } public int this[int i] { set { if (i != cache_pos) i = pos_to_idx (i); if (value < 0x10000) sb[i] = (char) value; else { char high = (char) (0xD800 + ((i - 0x10000) >> 10)); char low = (char) (0xDC00 + ((i - 0x10000) & 0x3FF)); if (! surrogate_high_p (sb[i])) sb.Insert (i, 0); sb[i++] = high; sb[i] = low; } } get { if (i != cache_pos) i = pos_to_idx (i); return (surrogate_high_p (sb[i]) ? i = ((sb[i] - 0xD800) << 10) + (sb[i + 1] - 0xDC00) + 0x10000 : sb[i]); } } } public class MTextProperty { } }