*** empty log message ***
[m17n/m17n-lib-cs.git] / MCharTable.cs
index 39e0714..1d9adc7 100644 (file)
@@ -1,6 +1,7 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.IO;
 using M17N;
 using M17N.Core;
 
@@ -78,8 +79,11 @@ namespace M17N.Core
 
     public override string ToString ()
     {
-      return String.Format ("[U+{0:X}..U+{1:X} {2}]", from, to,
-                           value == null ? "null" : value);
+      return ((from == to)
+             ? String.Format ("[U+{0:X} {1}]", from,
+                              value == null ? "null" : value)
+             : String.Format ("[U+{0:X}..U+{1:X} {2}]", from, to,
+                              value == null ? "null" : value));
     }
   }
 
@@ -176,8 +180,14 @@ namespace M17N.Core
     {
       set {
        MCharRange.CheckChar (from);
-       MCharRange.CheckChar (to);
-       set_range (from, to, value);
+
+       if (from == to)
+         Set (from, value);
+       else
+         {
+           MCharRange.CheckChar (to);
+           set_range (from, to, value);
+         }
       }
     }
 
@@ -290,4 +300,108 @@ namespace M17N.Core
       public void Dispose () {}
     }
   }
+
+  public class MCharProp : MCharTable
+  {
+    private static Dictionary<MSymbol, MDatabase> char_prop
+      = new Dictionary<MSymbol, MDatabase> ();
+
+    public static void Define (MSymbol prop, MDatabase mdb)
+      {
+       char_prop[prop] = mdb;
+      }
+
+    public MCharProp (MSymbol prop)
+      {
+       MDatabase mdb;
+
+       if (! char_prop.TryGetValue (prop, out mdb))
+         throw new Exception ("Undefined character property: " + prop);
+       mdb.Load (this);
+      }
+  }
+
+  public partial class MDatabase : IComparable<MDatabase>
+  {
+    private bool read_range (MStreamReader mst, out int from, out int to)
+    {
+      if (! mst.ReadInteger (out from))
+       {
+         to = from;
+         return false;
+       }
+      to = mst.Read ();
+      if (to < 0)
+       return false;
+      if (to != '-')
+       {
+         to = from;
+         return true;
+       }
+      return mst.ReadInteger (out to);
+    }
+
+    private MCharTable load_char_table (MCharTable table)
+    {
+      MSymbol type = tag[1];
+      
+      using (FileStream stream = FileInfo.OpenRead ())
+       {
+         MStreamReader mst = new MStreamReader (stream, ';', true);
+         int c, from, to;
+
+         while ((c = mst.Peek ()) >= 0)
+           {
+             if (c != '#'
+                 && read_range (mst, out from, out to)
+                 && mst.SkipSpace (out c))
+               {
+                 object value = null;
+
+                 if (type == MSymbol.integer)
+                   {
+                     int i;
+                     if (mst.ReadInteger (out i))
+                       value = i;
+                   }
+                 else if (type == MSymbol.symbol)
+                   {
+                     MSymbol sym;
+                     if (mst.ReadSymbol (out sym, -1))
+                       value = sym;
+                   }
+                 else if (type == MSymbol.mtext)
+                   {
+                     MText mt;
+                     if (mst.ReadMText (out mt))
+                       value = mt;
+                   }
+                 else if (type == MSymbol.plist)
+                   {
+                     value = new MPlist (mst);
+                   }
+                 else if (type == MSymbol.mstring)
+                   {
+                     string str;
+                     if (mst.ReadString (out str))
+                       value = str;
+                   }
+                 if (value != null)
+                   table[from, to] = value;
+               }
+             mst.ForwardLine ();
+           }
+       }
+      return table;
+    }
+
+    public object Load (MCharTable table)
+    {
+      if (loader != null || Info.Format != Mchar_table)
+       throw new ArgumentException ("Not a database of CharTable type");
+      if (! update_status ())
+       throw new Exception ("Database invalid");
+      return load_char_table (table);
+    }
+  }
 }