*** empty log message ***
authorhanda <handa>
Tue, 6 Jan 2009 00:09:01 +0000 (00:09 +0000)
committerhanda <handa>
Tue, 6 Jan 2009 00:09:01 +0000 (00:09 +0000)
MText.cs

index cd9b9db..7b7a9d5 100644 (file)
--- a/MText.cs
+++ b/MText.cs
@@ -43,43 +43,81 @@ namespace M17N.Core
     }
 
     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 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 ()
     {
-      cache_pos = cache_idx = 0;
-      plist = null;
       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 static int inc_idx (int i)
+    private int inc_idx (int i)
     {
-      return ((sb[i] >= 0xD800 && sb[i] < 0xDC00)
-             ? i + 2 : i + 1);
+      return (i + (surrogate_high_p (sb[i]) ? 2 : 1));
     }
 
-    private static int dec_idx (int i)
+    private int dec_idx (int i)
     {
-      return ((sb[i - 1] >= 0xDC00 && sb[i - 1] < 0xE000)
-             ? i - 2 : i - 1);
+      return (i - (surrogate_low_p (sb[i - 1]) ? 2 : 1));
     }
 
-    private static int pos_to_idx (int pos)
+    private int pos_to_idx (int pos)
     {
       int p, i;
       bool forward;
@@ -105,7 +143,7 @@ namespace M17N.Core
            return (cache_idx + pos - cache_pos);
          if (pos - cache_pos < nchars - pos)
            {
-             p = char_pos; i = char_idx;
+             p = cache_pos; i = cache_idx;
              forward = true;
            }
          else
@@ -129,14 +167,27 @@ namespace M17N.Core
        if (i != cache_pos)
          i = pos_to_idx (i);
        if (value < 0x10000)
-         this.sb[i] = (char) value;
+         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 { return this.sb[i]; }
+      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
   {